diff --git a/Makefile.umbrella.tmk b/Makefile.umbrella.tmk deleted file mode 100644 index 5dc0f13..0000000 --- a/Makefile.umbrella.tmk +++ /dev/null @@ -1,34 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 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. -# -# Repository umbrella makefile fragment for nvethernetrm -############################################################################### - -NV_REPOSITORY_COMPONENTS := \ - osi/core \ - osi/dma - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 8 -# End: -# vi: set tabstop=8 noexpandtab: diff --git a/docs/license.txt b/docs/license.txt deleted file mode 100644 index 390aecc..0000000 --- a/docs/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -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. diff --git a/include/ivc_core.h b/include/ivc_core.h deleted file mode 100644 index e8da34f..0000000 --- a/include/ivc_core.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 IVC_CORE_H -#define IVC_CORE_H - -#include - -/** - * @brief Ethernet Maximum IVC BUF - */ -#define ETHER_MAX_IVC_BUF 2048U - -/** - * @brief IVC maximum arguments - */ -#define MAX_ARGS 10 - -/** - * @brief IVC commands between OSD & OSI. - */ -typedef enum ivc_cmd { - core_init = 1, - core_deinit, - write_phy_reg, - read_phy_reg, - handle_ioctl, - init_macsec, - deinit_macsec, - handle_ns_irq_macsec, - handle_s_irq_macsec, - lut_config_macsec, - kt_config_macsec, - cipher_config, - loopback_config_macsec, - en_macsec, - config_macsec, - read_mmc_macsec, - dbg_buf_config_macsec, - dbg_events_config_macsec, - macsec_get_sc_lut_key_index, - macsec_update_mtu_size, -}ivc_cmd; - -/** - * @brief IVC arguments structure. - */ -typedef struct ivc_args { - /** Number of arguments */ - nveu32_t count; - /** arguments */ - nveu32_t arguments[MAX_ARGS]; -} ivc_args; - -/** - * @brief IVC core argument structure. - */ -typedef struct ivc_core_args { - /** Number of MTL queues enabled in MAC */ - nveu32_t num_mtl_queues; - /** Array of MTL queues */ - nveu32_t mtl_queues[OSI_EQOS_MAX_NUM_CHANS]; - /** List of MTL Rx queue mode that need to be enabled */ - nveu32_t rxq_ctrl[OSI_EQOS_MAX_NUM_CHANS]; - /** Rx MTl Queue mapping based on User Priority field */ - nveu32_t rxq_prio[OSI_EQOS_MAX_NUM_CHANS]; - /** Ethernet MAC address */ - nveu8_t mac_addr[OSI_ETH_ALEN]; - /** Tegra Pre-si platform info */ - nveu32_t pre_si; - /** VLAN tag stripping enable(1) or disable(0) */ - nveu32_t strip_vlan_tag; - /** pause frame support */ - nveu32_t pause_frames; - /** Current flow control settings */ - nveu32_t flow_ctrl; - /** Rx fifo size */ - nveu32_t rx_fifo_size; - /** Tx fifo size */ - nveu32_t tx_fifo_size; -} ivc_core_args; - -/** - * @brief macsec config structure. - */ -#ifdef MACSEC_SUPPORT -typedef struct macsec_config { - /** MACsec secure channel basic information */ - struct osi_macsec_sc_info sc_info; - /** MACsec enable or disable */ - unsigned int enable; - /** MACsec controller */ - unsigned short ctlr; - /** MACsec KT index */ - unsigned short kt_idx; - /** MACsec KT index */ - nveu32_t key_index; - /** MACsec SCI */ - nveu8_t sci[OSI_SCI_LEN]; -} macsec_config; -#endif - -/** - * @brief IVC message structure. - */ -typedef struct ivc_msg_common { - /** - * Status code returned as part of response message of IVC messages. - * Status code value is "0" for success and "< 0" for failure. - */ - nve32_t status; - /** ID of the CMD. */ - ivc_cmd cmd; - /** message count, used for debug */ - nveu32_t count; - - union { - /** IVC argument structure */ - ivc_args args; -#ifndef OSI_STRIPPED_LIB - /** avb algorithm structure */ - struct osi_core_avb_algorithm avb_algo; -#endif - /** OSI filter structure */ - struct osi_filter filter; - /** OSI HW features */ - struct osi_hw_features hw_feat; - /** MMC counters */ - struct osi_mmc_counters mmc; - /** core argument structure */ - ivc_core_args init_args; - /** ioctl command structure */ - struct osi_ioctl ioctl_data; -#ifdef MACSEC_SUPPORT - /** lut config */ - struct osi_macsec_lut_config lut_config; -#ifdef MACSEC_KEY_PROGRAM - /** kt config */ - struct osi_macsec_kt_config kt_config; -#endif - /** MACsec Debug buffer data structure */ - struct osi_macsec_dbg_buf_config dbg_buf_config; - /** MACsec config */ - macsec_config macsec_cfg; - /** macsec mmc counters */ - struct osi_macsec_mmc_counters macsec_mmc; - /** macsec IRQ stats */ - struct osi_macsec_irq_stats macsec_irq_stats; -#endif - }data; -} ivc_msg_common_t; - -/** - * @brief osd_ivc_send_cmd - OSD ivc send cmd - * - * @param[in] priv: OSD private data - * @param[in] ivc_buf: ivc_msg_common structure - * @param[in] len: length of data - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval ivc status - * @retval -1 on failure - */ -nve32_t osd_ivc_send_cmd(void *priv, ivc_msg_common_t *ivc_buf, - nveu32_t len); - -/** - * @brief ivc_get_core_safety_config - Get core safety config - * - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -void *ivc_get_core_safety_config(void); -#endif /* IVC_CORE_H */ diff --git a/include/mmc.h b/include/mmc.h deleted file mode 100644 index 0d3c7ab..0000000 --- a/include/mmc.h +++ /dev/null @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 INCLUDED_MMC_H -#define INCLUDED_MMC_H - -#include "../osi/common/type.h" -#include "osi_common.h" - -/** - * @brief osi_mmc_counters - The structure to hold RMON counter values - */ -struct osi_mmc_counters { - /** This counter provides the number of bytes transmitted, exclusive of - * preamble and retried bytes, in good and bad packets */ - nveu64_t mmc_tx_octetcount_gb; - /** This counter provides upper 32 bits of transmitted octet count */ - nveu64_t mmc_tx_octetcount_gb_h; - /** This counter provides the number of good and - * bad packets transmitted, exclusive of retried packets */ - nveu64_t mmc_tx_framecount_gb; - /** This counter provides upper 32 bits of transmitted good and bad - * packets count */ - nveu64_t mmc_tx_framecount_gb_h; - /** This counter provides number of good broadcast - * packets transmitted */ - nveu64_t mmc_tx_broadcastframe_g; - /** This counter provides upper 32 bits of transmitted good broadcast - * packets count */ - nveu64_t mmc_tx_broadcastframe_g_h; - /** This counter provides number of good multicast - * packets transmitted */ - nveu64_t mmc_tx_multicastframe_g; - /** This counter provides upper 32 bits of transmitted good multicast - * packet count */ - nveu64_t mmc_tx_multicastframe_g_h; - /** This counter provides the number of good and bad packets - * transmitted with length 64 bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_64_octets_gb; - /** This counter provides upper 32 bits of transmitted 64 octet size - * good and bad packets count */ - nveu64_t mmc_tx_64_octets_gb_h; - /** This counter provides the number of good and bad packets - * transmitted with length 65-127 bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_65_to_127_octets_gb; - /** Provides upper 32 bits of transmitted 65-to-127 octet size good and - * bad packets count */ - nveu64_t mmc_tx_65_to_127_octets_gb_h; - /** This counter provides the number of good and bad packets - * transmitted with length 128-255 bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_128_to_255_octets_gb; - /** This counter provides upper 32 bits of transmitted 128-to-255 - * octet size good and bad packets count */ - nveu64_t mmc_tx_128_to_255_octets_gb_h; - /** This counter provides the number of good and bad packets - * transmitted with length 256-511 bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_256_to_511_octets_gb; - /** This counter provides upper 32 bits of transmitted 256-to-511 - * octet size good and bad packets count. */ - nveu64_t mmc_tx_256_to_511_octets_gb_h; - /** This counter provides the number of good and bad packets - * transmitted with length 512-1023 bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_512_to_1023_octets_gb; - /** This counter provides upper 32 bits of transmitted 512-to-1023 - * octet size good and bad packets count.*/ - nveu64_t mmc_tx_512_to_1023_octets_gb_h; - /** This counter provides the number of good and bad packets - * transmitted with length 1024-max bytes, exclusive of preamble and - * retried packets */ - nveu64_t mmc_tx_1024_to_max_octets_gb; - /** This counter provides upper 32 bits of transmitted 1024-tomaxsize - * octet size good and bad packets count. */ - nveu64_t mmc_tx_1024_to_max_octets_gb_h; - /** This counter provides the number of good and bad unicast packets */ - nveu64_t mmc_tx_unicast_gb; - /** This counter provides upper 32 bits of transmitted good bad - * unicast packets count */ - nveu64_t mmc_tx_unicast_gb_h; - /** This counter provides the number of good and bad - * multicast packets */ - nveu64_t mmc_tx_multicast_gb; - /** This counter provides upper 32 bits of transmitted good bad - * multicast packets count */ - nveu64_t mmc_tx_multicast_gb_h; - /** This counter provides the number of good and bad - * broadcast packets */ - nveu64_t mmc_tx_broadcast_gb; - /** This counter provides upper 32 bits of transmitted good bad - * broadcast packets count */ - nveu64_t mmc_tx_broadcast_gb_h; - /** This counter provides the number of abort packets due to - * underflow error */ - nveu64_t mmc_tx_underflow_error; - /** This counter provides upper 32 bits of abort packets due to - * underflow error */ - nveu64_t mmc_tx_underflow_error_h; - /** This counter provides the number of successfully transmitted - * packets after a single collision in the half-duplex mode */ - nveu64_t mmc_tx_singlecol_g; - /** This counter provides the number of successfully transmitted - * packets after a multi collision in the half-duplex mode */ - nveu64_t mmc_tx_multicol_g; - /** This counter provides the number of successfully transmitted - * after a deferral in the half-duplex mode */ - nveu64_t mmc_tx_deferred; - /** This counter provides the number of packets aborted because of - * late collision error */ - nveu64_t mmc_tx_latecol; - /** This counter provides the number of packets aborted because of - * excessive (16) collision errors */ - nveu64_t mmc_tx_exesscol; - /** This counter provides the number of packets aborted because of - * carrier sense error (no carrier or loss of carrier) */ - nveu64_t mmc_tx_carrier_error; - /** This counter provides the number of bytes transmitted, - * exclusive of preamble, only in good packets */ - nveu64_t mmc_tx_octetcount_g; - /** This counter provides upper 32 bytes of bytes transmitted, - * exclusive of preamble, only in good packets */ - nveu64_t mmc_tx_octetcount_g_h; - /** This counter provides the number of good packets transmitted */ - nveu64_t mmc_tx_framecount_g; - /** This counter provides upper 32 bytes of good packets transmitted */ - nveu64_t mmc_tx_framecount_g_h; - /** This counter provides the number of packets aborted because of - * excessive deferral error - * (deferred for more than two max-sized packet times) */ - nveu64_t mmc_tx_excessdef; - /** This counter provides the number of good Pause - * packets transmitted */ - nveu64_t mmc_tx_pause_frame; - /** This counter provides upper 32 bytes of good Pause - * packets transmitted */ - nveu64_t mmc_tx_pause_frame_h; - /** This counter provides the number of good VLAN packets transmitted */ - nveu64_t mmc_tx_vlan_frame_g; - /** This counter provides upper 32 bytes of good VLAN packets - * transmitted */ - nveu64_t mmc_tx_vlan_frame_g_h; - /** 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 */ - nveu64_t mmc_tx_osize_frame_g; - /** This counter provides the number of good and bad packets received */ - nveu64_t mmc_rx_framecount_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received */ - nveu64_t mmc_rx_framecount_gb_h; - /** This counter provides the number of bytes received by DWC_ther_qos, - * exclusive of preamble, in good and bad packets */ - nveu64_t mmc_rx_octetcount_gb; - /** This counter provides upper 32 bytes of bytes received by - * DWC_ether_qos, exclusive of preamble, in good and bad packets */ - nveu64_t mmc_rx_octetcount_gb_h; - /** This counter provides the number of bytes received by DWC_ether_qos, - * exclusive of preamble, in good and bad packets */ - nveu64_t mmc_rx_octetcount_g; - /** This counter provides upper 32 bytes of bytes received by - * DWC_ether_qos, exclusive of preamble, in good and bad packets */ - nveu64_t mmc_rx_octetcount_g_h; - /** This counter provides the number of good - * broadcast packets received */ - nveu64_t mmc_rx_broadcastframe_g; - /** This counter provides upper 32 bytes of good - * broadcast packets received */ - nveu64_t mmc_rx_broadcastframe_g_h; - /** This counter provides the number of good - * multicast packets received */ - nveu64_t mmc_rx_multicastframe_g; - /** This counter provides upper 32 bytes of good - * multicast packets received */ - nveu64_t mmc_rx_multicastframe_g_h; - /** This counter provides the number of packets - * received with CRC error */ - nveu64_t mmc_rx_crc_error; - /** This counter provides upper 32 bytes of packets - * received with CRC error */ - nveu64_t mmc_rx_crc_error_h; - /** This counter provides the number of packets received with - * alignment (dribble) error. It is valid only in 10/100 mode */ - nveu64_t mmc_rx_align_error; - /** This counter provides the number of packets received with - * runt (length less than 64 bytes and CRC error) error */ - nveu64_t mmc_rx_runt_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 */ - nveu64_t mmc_rx_jabber_error; - /** This counter provides the number of packets received with length - * less than 64 bytes, without any errors */ - nveu64_t mmc_rx_undersize_g; - /** This counter provides the number of packets received without error, - * with length greater than the maxsize */ - nveu64_t mmc_rx_oversize_g; - /** This counter provides the number of good and bad packets received - * with length 64 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_64_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 64 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_64_octets_gb_h; - /** This counter provides the number of good and bad packets received - * with length 65-127 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_65_to_127_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 65-127 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_65_to_127_octets_gb_h; - /** This counter provides the number of good and bad packets received - * with length 128-255 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_128_to_255_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 128-255 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_128_to_255_octets_gb_h; - /** This counter provides the number of good and bad packets received - * with length 256-511 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_256_to_511_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 256-511 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_256_to_511_octets_gb_h; - /** This counter provides the number of good and bad packets received - * with length 512-1023 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_512_to_1023_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 512-1023 bytes, exclusive of the preamble */ - nveu64_t mmc_rx_512_to_1023_octets_gb_h; - /** This counter provides the number of good and bad packets received - * with length 1024-maxbytes, exclusive of the preamble */ - nveu64_t mmc_rx_1024_to_max_octets_gb; - /** This counter provides upper 32 bytes of good and bad packets - * received with length 1024-maxbytes, exclusive of the preamble */ - nveu64_t mmc_rx_1024_to_max_octets_gb_h; - /** This counter provides the number of good unicast packets received */ - nveu64_t mmc_rx_unicast_g; - /** This counter provides upper 32 bytes of good unicast packets - * received */ - nveu64_t mmc_rx_unicast_g_h; - /** 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 */ - nveu64_t mmc_rx_length_error; - /** This counter provides upper 32 bytes of packets received with - * length error (Length Type field not equal to packet size), for all - * packets with valid length field */ - nveu64_t mmc_rx_length_error_h; - /** 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) */ - nveu64_t mmc_rx_outofrangetype; - /** This counter provides upper 32 bytes of packets received with - * length field not equal to the valid packet size (greater than 1,500 - * but less than 1,536) */ - nveu64_t mmc_rx_outofrangetype_h; - /** This counter provides the number of good and valid Pause packets - * received */ - nveu64_t mmc_rx_pause_frames; - /** This counter provides upper 32 bytes of good and valid Pause packets - * received */ - nveu64_t mmc_rx_pause_frames_h; - /** This counter provides the number of missed received packets - * because of FIFO overflow in DWC_ether_qos */ - nveu64_t mmc_rx_fifo_overflow; - /** This counter provides upper 32 bytes of missed received packets - * because of FIFO overflow in DWC_ether_qos */ - nveu64_t mmc_rx_fifo_overflow_h; - /** This counter provides the number of good and bad VLAN packets - * received */ - nveu64_t mmc_rx_vlan_frames_gb; - /** This counter provides upper 32 bytes of good and bad VLAN packets - * received */ - nveu64_t mmc_rx_vlan_frames_gb_h; - /** This counter provides the number of packets received with error - * because of watchdog timeout error */ - nveu64_t mmc_rx_watchdog_error; - /** This counter provides the number of packets received with Receive - * error or Packet Extension error on the GMII or MII interface */ - nveu64_t 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 */ - nveu64_t mmc_rx_ctrl_frames_g; - /** This counter provides the number of microseconds Tx LPI is asserted - * in the MAC controller */ - nveu64_t mmc_tx_lpi_usec_cntr; - /** This counter provides the number of times MAC controller has - * entered Tx LPI. */ - nveu64_t mmc_tx_lpi_tran_cntr; - /** This counter provides the number of microseconds Rx LPI is asserted - * in the MAC controller */ - nveu64_t mmc_rx_lpi_usec_cntr; - /** This counter provides the number of times MAC controller has - * entered Rx LPI.*/ - nveu64_t mmc_rx_lpi_tran_cntr; - /** This counter provides the number of good IPv4 datagrams received - * with the TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv4_gd; - /** This counter provides upper 32 bytes of good IPv4 datagrams received - * with the TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv4_gd_h; - /** RxIPv4 Header Error Packets */ - nveu64_t mmc_rx_ipv4_hderr; - /** RxIPv4 of upper 32 bytes of Header Error Packets */ - nveu64_t mmc_rx_ipv4_hderr_h; - /** This counter provides the number of IPv4 datagram packets received - * that did not have a TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv4_nopay; - /** This counter provides upper 32 bytes of IPv4 datagram packets - * received that did not have a TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv4_nopay_h; - /** This counter provides the number of good IPv4 datagrams received - * with fragmentation */ - nveu64_t mmc_rx_ipv4_frag; - /** This counter provides upper 32 bytes of good IPv4 datagrams received - * with fragmentation */ - nveu64_t mmc_rx_ipv4_frag_h; - /** This counter provides the number of good IPv4 datagrams received - * that had a UDP payload with checksum disabled */ - nveu64_t mmc_rx_ipv4_udsbl; - /** This counter provides upper 32 bytes of good IPv4 datagrams received - * that had a UDP payload with checksum disabled */ - nveu64_t mmc_rx_ipv4_udsbl_h; - /** This counter provides the number of good IPv6 datagrams received - * with the TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv6_gd_octets; - /** This counter provides upper 32 bytes of good IPv6 datagrams received - * with the TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv6_gd_octets_h; - /** This counter provides the number of IPv6 datagrams received - * with header (length or version mismatch) errors */ - nveu64_t mmc_rx_ipv6_hderr_octets; - /** This counter provides the number of IPv6 datagrams received - * with header (length or version mismatch) errors */ - nveu64_t mmc_rx_ipv6_hderr_octets_h; - /** This counter provides the number of IPv6 datagram packets received - * that did not have a TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv6_nopay_octets; - /** This counter provides upper 32 bytes of IPv6 datagram packets - * received that did not have a TCP, UDP, or ICMP payload */ - nveu64_t mmc_rx_ipv6_nopay_octets_h; - /* Protocols */ - /** This counter provides the number of good IP datagrams received by - * DWC_ether_qos with a good UDP payload */ - nveu64_t mmc_rx_udp_gd; - /** This counter provides upper 32 bytes of good IP datagrams received - * by DWC_ether_qos with a good UDP payload */ - nveu64_t mmc_rx_udp_gd_h; - /** 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 */ - nveu64_t mmc_rx_udp_err; - /** This counter provides upper 32 bytes 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 */ - nveu64_t mmc_rx_udp_err_h; - /** This counter provides the number of good IP datagrams received - * with a good TCP payload */ - nveu64_t mmc_rx_tcp_gd; - /** This counter provides the number of good IP datagrams received - * with a good TCP payload */ - nveu64_t mmc_rx_tcp_gd_h; - /** This counter provides upper 32 bytes of good IP datagrams received - * with a good TCP payload */ - nveu64_t mmc_rx_tcp_err; - /** This counter provides upper 32 bytes of good IP datagrams received - * with a good TCP payload */ - nveu64_t mmc_rx_tcp_err_h; - /** This counter provides the number of good IP datagrams received - * with a good ICMP payload */ - nveu64_t mmc_rx_icmp_gd; - /** This counter provides upper 32 bytes of good IP datagrams received - * with a good ICMP payload */ - nveu64_t mmc_rx_icmp_gd_h; - /** This counter provides the number of good IP datagrams received - * whose ICMP payload has a checksum error */ - nveu64_t mmc_rx_icmp_err; - /** This counter provides upper 32 bytes of good IP datagrams received - * whose ICMP payload has a checksum error */ - nveu64_t mmc_rx_icmp_err_h; - /** 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 */ - nveu64_t mmc_rx_ipv4_gd_octets; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv4_gd_octets_h; - /** This counter provides the number of bytes received in IPv4 datagram - * 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 */ - nveu64_t mmc_rx_ipv4_hderr_octets; - /** This counter provides upper 32 bytes received in IPv4 datagram - * 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 */ - nveu64_t mmc_rx_ipv4_hderr_octets_h; - /** This counter provides the number of bytes received in IPv4 datagram - * 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 */ - nveu64_t mmc_rx_ipv4_nopay_octets; - /** This counter provides upper 32 bytes received in IPv4 datagram - * 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 */ - nveu64_t mmc_rx_ipv4_nopay_octets_h; - /** 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 */ - nveu64_t mmc_rx_ipv4_frag_octets; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv4_frag_octets_h; - /** 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 */ - nveu64_t mmc_rx_ipv4_udsbl_octets; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv4_udsbl_octets_h; - /** 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 */ - nveu64_t mmc_rx_ipv6_gd; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv6_gd_h; - /** 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 */ - nveu64_t mmc_rx_ipv6_hderr; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv6_hderr_h; - /** 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 */ - nveu64_t mmc_rx_ipv6_nopay; - /** This counter provides upper 32 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 */ - nveu64_t mmc_rx_ipv6_nopay_h; - /* Protocols */ - /** This counter provides the number of bytes received in a good UDP - * segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_udp_gd_octets; - /** This counter provides upper 32 bytes received in a good UDP - * segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_udp_gd_octets_h; - /** This counter provides the number of bytes received in a UDP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_udp_err_octets; - /** This counter provides upper 32 bytes received in a UDP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_udp_err_octets_h; - /** This counter provides the number of bytes received in a good - * TCP segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_tcp_gd_octets; - /** This counter provides upper 32 bytes received in a good - * TCP segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_tcp_gd_octets_h; - /** This counter provides the number of bytes received in a TCP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_tcp_err_octets; - /** This counter provides upper 32 bytes received in a TCP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_tcp_err_octets_h; - /** This counter provides the number of bytes received in a good - * ICMP segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_icmp_gd_octets; - /** This counter provides upper 32 bytes received in a good - * ICMP segment. This counter does not count IP header bytes */ - nveu64_t mmc_rx_icmp_gd_octets_h; - /** This counter provides the number of bytes received in a ICMP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_icmp_err_octets; - /** This counter provides upper 32 bytes received in a ICMP - * segment that had checksum errors. This counter does not count - * IP header bytes */ - nveu64_t mmc_rx_icmp_err_octets_h; - /** This counter provides the number of additional mPackets - * transmitted due to preemption */ - unsigned long mmc_tx_fpe_frag_cnt; - /** This counter provides the count of number of times a hold - * request is given to MAC */ - unsigned long mmc_tx_fpe_hold_req_cnt; - /** This counter provides the number of MAC frames with reassembly - * errors on the Receiver, due to mismatch in the fragment - * count value */ - unsigned long mmc_rx_packet_reass_err_cnt; - /** This counter the number of received MAC frames rejected - * due to unknown SMD value and MAC frame fragments rejected due - * to arriving with an SMD-C when there was no preceding preempted - * frame */ - unsigned long mmc_rx_packet_smd_err_cnt; - /** This counter provides the number of MAC frames that were - * successfully reassembled and delivered to MAC */ - unsigned long mmc_rx_packet_asm_ok_cnt; - /** This counter provides the number of additional mPackets received - * due to preemption */ - unsigned long mmc_rx_fpe_fragment_cnt; -}; - -/** - * @brief osi_xtra_stat_counters - OSI core extra stat counters - */ -struct osi_xtra_stat_counters { - /** RX buffer unavailable irq count */ - nveu64_t rx_buf_unavail_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Transmit Process Stopped irq count */ - nveu64_t tx_proc_stopped_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Transmit Buffer Unavailable irq count */ - nveu64_t tx_buf_unavail_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Receive Process Stopped irq count */ - nveu64_t rx_proc_stopped_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Receive Watchdog Timeout irq count */ - nveu64_t rx_watchdog_irq_n; - /** Fatal Bus Error irq count */ - nveu64_t fatal_bus_error_irq_n; - /** rx skb allocation failure count */ - nveu64_t re_alloc_rxbuf_failed[OSI_MGBE_MAX_NUM_QUEUES]; - /** TX per channel interrupt count */ - nveu64_t tx_normal_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** TX per channel SW timer callback count */ - nveu64_t tx_usecs_swtimer_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** RX per channel interrupt count */ - nveu64_t rx_normal_irq_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** link connect count */ - nveu64_t link_connect_count; - /** link disconnect count */ - nveu64_t link_disconnect_count; - /** lock fail count node addition */ - nveu64_t ts_lock_add_fail; - /** lock fail count node removal */ - nveu64_t ts_lock_del_fail; -}; - -#ifdef MACSEC_SUPPORT -/** - * @brief The structure hold macsec statistics counters - */ -struct osi_macsec_mmc_counters { - /** This counter provides the number of controller port macsec - * untaged packets */ - nveul64_t rx_pkts_no_tag; - /** This counter provides the number of controller port macsec - * untaged packets validateFrame != strict */ - nveul64_t rx_pkts_untagged; - /** This counter provides the number of invalid tag or icv packets */ - nveul64_t rx_pkts_bad_tag; - /** This counter provides the number of no sc lookup hit or sc match - * packets */ - nveul64_t rx_pkts_no_sa_err; - /** This counter provides the number of no sc lookup hit or sc match - * packets validateFrame != strict */ - nveul64_t rx_pkts_no_sa; - /** This counter provides the number of late packets - *received PN < lowest PN */ - nveul64_t rx_pkts_late[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of overrun packets */ - nveul64_t rx_pkts_overrun; - /** This counter provides the number of octets after IVC passing */ - nveul64_t rx_octets_validated; - /** This counter provides the number not valid packets */ - nveul64_t rx_pkts_not_valid[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of invalid packets */ - nveul64_t in_pkts_invalid[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of in packet delayed */ - nveul64_t rx_pkts_delayed[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of in packets un checked */ - nveul64_t rx_pkts_unchecked[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of in packets ok */ - nveul64_t rx_pkts_ok[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of out packets untaged */ - nveul64_t tx_pkts_untaged; - /** This counter provides the number of out too long */ - nveul64_t tx_pkts_too_long; - /** This counter provides the number of out packets protected */ - nveul64_t tx_pkts_protected[OSI_MACSEC_SC_INDEX_MAX]; - /** This counter provides the number of out octets protected */ - nveul64_t tx_octets_protected; -}; -#endif /* MACSEC_SUPPORT */ -#endif /* INCLUDED_MMC_H */ diff --git a/include/osi_common.h b/include/osi_common.h deleted file mode 100644 index 8f34012..0000000 --- a/include/osi_common.h +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2018-2023, 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 INCLUDED_OSI_COMMON_H -#define INCLUDED_OSI_COMMON_H - -#include "../osi/common/type.h" - -/** - * @addtogroup FC Flow Control Threshold Macros - * - * @brief These bits control the threshold (fill-level of Rx queue) at which - * the flow control is asserted or de-asserted - * @{ - */ -#define FULL_MINUS_1_5K (unsigned int)1 -#define FULL_MINUS_2_K (unsigned int)2 -#define FULL_MINUS_2_5K (unsigned int)3 -#define FULL_MINUS_3_K (unsigned int)4 -#define FULL_MINUS_4_K (unsigned int)6 -#define FULL_MINUS_6_K (unsigned int)10 -#define FULL_MINUS_10_K (unsigned int)18 -#define FULL_MINUS_13_K (unsigned int)24 -#define FULL_MINUS_14_K (unsigned int)26 -#define FULL_MINUS_16_K (unsigned int)30 -#define FULL_MINUS_18_K (unsigned int)34 -#define FULL_MINUS_21_K (unsigned int)40 -#define FULL_MINUS_24_K (unsigned int)46 -#define FULL_MINUS_29_K (unsigned int)56 -#define FULL_MINUS_31_K (unsigned int)60 -#define FULL_MINUS_32_K (unsigned int)62 -/** @} */ - -/** - * @addtogroup OSI-Helper OSI Helper MACROS - * @{ - */ -#define OSI_UNLOCKED 0x0U -#define OSI_LOCKED 0x1U -#define OSI_NSEC_PER_SEC 1000000000ULL - -#ifndef OSI_STRIPPED_LIB -#define OSI_MAX_RX_COALESCE_USEC 1020U -#define OSI_EQOS_MIN_RX_COALESCE_USEC 5U -#define OSI_MGBE_MIN_RX_COALESCE_USEC 6U -#define OSI_MIN_RX_COALESCE_FRAMES 1U -#define OSI_MAX_TX_COALESCE_USEC 1020U -#define OSI_MIN_TX_COALESCE_USEC 32U -#define OSI_MIN_TX_COALESCE_FRAMES 1U -#endif /* !OSI_STRIPPED_LIB */ - -/* Compiler hints for branch prediction */ -#define osi_unlikely(x) __builtin_expect(!!(x), 0) -/** @} */ - -#ifndef OSI_STRIPPED_LIB -/** - * @addtogroup - LPI-Timers LPI configuration macros - * - * @brief LPI timers and config register field masks. - * @{ - */ -/* LPI LS timer - minimum time (in milliseconds) for which the link status from - * PHY should be up before the LPI pattern can be transmitted to the PHY. - * Default 1sec. - */ -#define OSI_DEFAULT_LPI_LS_TIMER (nveu32_t)1000 -#define OSI_LPI_LS_TIMER_MASK 0x3FFU -#define OSI_LPI_LS_TIMER_SHIFT 16U -/* LPI TW timer - minimum time (in microseconds) for which MAC wait after it - * stops transmitting LPI pattern before resuming normal tx. - * Default 21us - */ -#define OSI_DEFAULT_LPI_TW_TIMER 0x15U -#define OSI_LPI_TW_TIMER_MASK 0xFFFFU -/* LPI entry timer - Time in microseconds that MAC will wait to enter LPI mode - * after all tx is complete. - * Default 1sec. - */ -#define OSI_LPI_ENTRY_TIMER_MASK 0xFFFF8U - -/* LPI entry timer - Time in microseconds that MAC will wait to enter LPI mode - * after all tx is complete. Default 1sec. - */ -#define OSI_DEFAULT_TX_LPI_TIMER 0xF4240U - -/* Max Tx LPI timer (in usecs) based on the timer value field length in HW - * MAC_LPI_ENTRY_TIMER register */ -#define OSI_MAX_TX_LPI_TIMER 0xFFFF8U - -/* Min Tx LPI timer (in usecs) based on the timer value field length in HW - * MAC_LPI_ENTRY_TIMER register */ -#define OSI_MIN_TX_LPI_TIMER 0x8U - -/* Time in 1 microseconds tic counter used as reference for all LPI timers. - * It is clock rate of CSR slave port (APB clock[eqos_pclk] in eqos) minus 1 - * Current eqos_pclk is 204MHz - */ -#define OSI_LPI_1US_TIC_COUNTER_DEFAULT 0xCBU -#define OSI_LPI_1US_TIC_COUNTER_MASK 0xFFFU -/** @} */ -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#ifndef OSI_STRIPPED_LIB -#define OSI_PAUSE_FRAMES_ENABLE 1U -#define OSI_PTP_REQ_CLK_FREQ 250000000U -#define OSI_FLOW_CTRL_DISABLE 0U -#define OSI_MAX_24BITS 0xFFFFFFU -#define OSI_MAX_28BITS 0xFFFFFFFU -#define OSI_MAX_32BITS 0xFFFFFFFFU -#define OSI_MASK_16BITS 0xFFFFU -#define OSI_MASK_20BITS 0xFFFFFU -#define OSI_MASK_24BITS 0xFFFFFFU -#define OSI_GCL_SIZE_64 64U -#define OSI_GCL_SIZE_128 128U -#define OSI_GCL_SIZE_256 256U -#define OSI_GCL_SIZE_512 512U -#define OSI_GCL_SIZE_1024 1024U - -#define OSI_POLL_COUNT 1000U - -#define OSI_ADDRESS_32BIT 0 -#define OSI_ADDRESS_40BIT 1 -#define OSI_ADDRESS_48BIT 2 -#endif /* !OSI_STRIPPED_LIB */ - -#ifndef UINT_MAX -#define UINT_MAX (~0U) -#endif -#ifndef INT_MAX -#define INT_MAX (0x7FFFFFFF) -#endif -/** @} */ - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#define OSI_UCHAR_MAX (0xFFU) - -/* Logging defines */ -/* log levels */ - -#define OSI_LOG_INFO 1U -#define OSI_LOG_WARN 2U -#define OSI_LOG_ERR 3U -/* Error types */ -#define OSI_LOG_ARG_OUTOFBOUND 1U -#define OSI_LOG_ARG_INVALID 2U -#define OSI_LOG_ARG_HW_FAIL 4U -#define OSI_LOG_WARN 2U -#ifndef OSI_STRIPPED_LIB -#define OSI_LOG_ARG_OPNOTSUPP 3U -#endif /* !OSI_STRIPPED_LIB */ -/* Default maximum Giant Packet Size Limit is 16K */ -#define OSI_MAX_MTU_SIZE 16383U -/* MAC Tx/Rx Idle retry and delay count */ -#define OSI_TXRX_IDLE_RETRY 5000U -#define OSI_DELAY_COUNT 10U - -#define EQOS_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x1160U) -#define MGBE_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x3160U) -#define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) - -/* FIXME add logic based on HW version */ -#define OSI_EQOS_MAX_NUM_CHANS 8U -#define OSI_EQOS_MAX_NUM_QUEUES 8U -#define OSI_MGBE_MAX_L3_L4_FILTER 8U -#define OSI_MGBE_MAX_NUM_CHANS 10U -#define OSI_MGBE_MAX_NUM_QUEUES 10U -#define OSI_EQOS_XP_MAX_CHANS 4U - -/* MACSEC max SC's supported 16*/ -#define OSI_MACSEC_SC_INDEX_MAX 16 - -/* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ -#define OSI_EQOS_MAX_HASH_REGS 4U - -#define MAC_VERSION 0x110 -#define MAC_VERSION_SNVER_MASK 0x7FU - -#define OSI_MAC_HW_EQOS 0U -#define OSI_MAC_HW_MGBE 1U -#define OSI_ETH_ALEN 6U -#define OSI_MAX_VM_IRQS 5U - -#define OSI_NULL ((void *)0) -#define OSI_ENABLE 1U -#define OSI_NONE 0U -#define OSI_NONE_SIGNED 0 -#define OSI_DISABLE 0U - -#define OSI_BIT(nr) ((nveu32_t)1 << (nr)) - -#define OSI_EQOS_MAC_4_10 0x41U -#define OSI_EQOS_MAC_5_00 0x50U -#define OSI_EQOS_MAC_5_10 0x51U -#define OSI_EQOS_MAC_5_30 0x53U -#define OSI_MGBE_MAC_3_00 0x30U -#define OSI_MGBE_MAC_3_10 0x31U -#define OSI_MGBE_MAC_4_00 0x40U - -#define OSI_MAX_VM_IRQS 5U -#define OSI_IP4_FILTER 0U -#define OSI_IP6_FILTER 1U - -#ifndef OSI_STRIPPED_LIB -#define OSI_L2_FILTER_INDEX_ANY 127U -#define OSI_HASH_FILTER_MODE 1U -#define OSI_L4_FILTER_TCP 0U -#define OSI_L4_FILTER_UDP 1U -#define OSI_PERFECT_FILTER_MODE 0U - -#define NV_ETH_FCS_LEN 0x4U -#define NV_ETH_FRAME_LEN 1514U - -#define MAX_ETH_FRAME_LEN_DEFAULT \ - (NV_ETH_FRAME_LEN + NV_ETH_FCS_LEN + NV_VLAN_HLEN) -#define OSI_MTU_SIZE_16K 16000U -#define OSI_MTU_SIZE_8K 8000U -#define OSI_MTU_SIZE_4K 4000U -#define OSI_MTU_SIZE_2K 2000U -#define OSI_INVALID_CHAN_NUM 0xFFU -#endif /* OSI_STRIPPED_LIB */ -/** @} */ - -/** - * @addtogroup OSI-DEBUG helper macros - * - * @brief OSI debug type macros - * @{ - */ -#ifdef OSI_DEBUG -#define OSI_DEBUG_TYPE_DESC 1U -#define OSI_DEBUG_TYPE_REG 2U -#define OSI_DEBUG_TYPE_STRUCTS 3U -#endif /* OSI_DEBUG */ - -#ifndef OSI_STRIPPED_LIB -/** - * @addtogroup MTL queue operation mode - * - * @brief MTL queue operation mode options - * @{ - */ -#define OSI_MTL_QUEUE_DISABLED 0x0U -#define OSI_MTL_QUEUE_AVB 0x1U -#define OSI_MTL_QUEUE_ENABLE 0x2U -#define OSI_MTL_QUEUE_MODEMAX 0x3U -/** @} */ - -/** - * @addtogroup EQOS_MTL MTL queue AVB algorithm mode - * - * @brief MTL AVB queue algorithm type - * @{ - */ -#define OSI_MTL_TXQ_AVALG_CBS 1U -#define OSI_MTL_TXQ_AVALG_SP 0U -/** @} */ -#endif /* OSI_STRIPPED_LIB */ - -/** - * @brief unused function attribute - */ -#define OSI_UNUSED __attribute__((__unused__)) - -/** - * @brief osi_update_stats_counter - update value by increment passed - * as parameter - * @note - * Algorithm: - * - Check for boundary and return sum - * - * @param[in] last_value: last value of stat counter - * @param[in] incr: increment value - * - * @note Input parameter should be only nveu64_t type - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on sucess - * @retval -1 on failure - */ -static inline nveu64_t osi_update_stats_counter(nveu64_t last_value, - nveu64_t incr) -{ - nveu64_t temp = last_value + incr; - - if (temp < last_value) { - /* Stats overflow, so reset it to zero */ - return 0UL; - } - - return temp; -} -#endif /* OSI_COMMON_H */ diff --git a/include/osi_core.h b/include/osi_core.h deleted file mode 100644 index 6648a7a..0000000 --- a/include/osi_core.h +++ /dev/null @@ -1,2871 +0,0 @@ -/* - * Copyright (c) 2018-2023, 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 INCLUDED_OSI_CORE_H -#define INCLUDED_OSI_CORE_H - -#include -#include "mmc.h" - -struct ivc_msg_common; -/** - * @addtogroup typedef related info - * - * @brief typedefs that indicate size and signness - * @{ - */ -/* Following added to avoid misraC 4.6 - * Here we are defining intermediate type - */ -/** intermediate type for unsigned short */ -typedef unsigned short my_uint16_t; -/** intermediate type for long long */ -typedef long long my_lint_64; - -/* Actual type used in code */ -/** typedef equivalent to unsigned short */ -typedef my_uint16_t nveu16_t; -/** typedef equivalent to long long */ -typedef my_lint_64 nvel64_t; -/** @} */ - -#ifdef MACSEC_SUPPORT -/** - * @addtogroup MACSEC related helper MACROs - * - * @brief MACSEC generic helper MACROs - * @{ - */ -#define OSI_MAX_NUM_SC 8U -#define OSI_SCI_LEN 8U -#define OSI_KEY_LEN_128 16U -#define OSI_KEY_LEN_256 32U -#define OSI_NUM_CTLR 2U -/** @} */ -#endif /* MACSEC_SUPPORT */ - -/** - * @addtogroup PTP PTP related information - * - * @brief PTP SSINC values - * @{ - */ -#define OSI_PTP_SSINC_16 16U -#define OSI_PTP_SSINC_4 4U -/** @} */ - -/** - * @addtogroup PTP PTP related information - * - * @brief PTP MAC-to-MAC sync role - */ -#define OSI_PTP_M2M_INACTIVE 0U -#define OSI_PTP_M2M_PRIMARY 1U -#define OSI_PTP_M2M_SECONDARY 2U -/** @} */ - -/** - * @addtogroup EQOS_PTP PTP Helper MACROS - * - * @brief EQOS PTP MAC Time stamp control reg bit fields - * @{ - */ -#define OSI_MAC_TCR_TSENA OSI_BIT(0) -#define OSI_MAC_TCR_TSCFUPDT OSI_BIT(1) -#define OSI_MAC_TCR_TSENALL OSI_BIT(8) -#define OSI_MAC_TCR_TSCTRLSSR OSI_BIT(9) -#define OSI_MAC_TCR_TSVER2ENA OSI_BIT(10) -#define OSI_MAC_TCR_TSIPENA OSI_BIT(11) -#define OSI_MAC_TCR_TSIPV6ENA OSI_BIT(12) -#define OSI_MAC_TCR_TSIPV4ENA OSI_BIT(13) -#define OSI_MAC_TCR_TSEVENTENA OSI_BIT(14) -#define OSI_MAC_TCR_TSMASTERENA OSI_BIT(15) -#define OSI_MAC_TCR_SNAPTYPSEL_1 OSI_BIT(16) -#define OSI_MAC_TCR_SNAPTYPSEL_2 OSI_BIT(17) -#define OSI_MAC_TCR_CSC OSI_BIT(19) -#define OSI_MAC_TCR_AV8021ASMEN OSI_BIT(28) -#define OSI_MAC_TCR_SNAPTYPSEL_3 (OSI_BIT(16) | OSI_BIT(17)) -#define OSI_MAC_TCR_TXTSSMIS OSI_BIT(31) -/** @} */ - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#define EQOS_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x1134U) -#define EQOS_MAX_MAC_ADDRESS_FILTER 128U -#define EQOS_MAX_L3_L4_FILTER 8U -#define EQOS_MAX_HTR_REGS 8U -#define OSI_MGBE_MAX_MAC_ADDRESS_FILTER 32U -#define OSI_DA_MATCH 0U -#define OSI_INV_MATCH 1U -#define OSI_AMASK_DISABLE 0U -#define OSI_CHAN_ANY 0xFFU -#define OSI_MAX_TC_NUM 8U -#define OSI_DFLT_MTU_SIZE 1500U -#define OSI_MTU_SIZE_9000 9000U -/* HW supports 8 Hash table regs, but eqos_validate_core_regs only checks 4 */ -#define OSI_EQOS_MAX_HASH_REGS 4U -#define OSI_ETH_ALEN 6U - -#define OSI_FLOW_CTRL_TX OSI_BIT(0) -#define OSI_FLOW_CTRL_RX OSI_BIT(1) - -#define OSI_FULL_DUPLEX 1 -#define OSI_HALF_DUPLEX 0 - -#define OSI_IP4_FILTER 0U -#define OSI_IP6_FILTER 1U -#define OSI_IPV6_MATCH 1U -#define OSI_IPV4_MATCH 0U - -/* L2 filter operations supported by OSI layer. These operation modes shall be - * set by OSD driver as input to update registers accordingly. - */ -#define OSI_OPER_EN_PROMISC OSI_BIT(0) -#define OSI_OPER_DIS_PROMISC OSI_BIT(1) -#define OSI_OPER_EN_ALLMULTI OSI_BIT(2) -#define OSI_OPER_DIS_ALLMULTI OSI_BIT(3) -#define OSI_OPER_EN_L2_DA_INV OSI_BIT(4) -#define OSI_OPER_DIS_L2_DA_INV OSI_BIT(5) -#define OSI_OPER_EN_PERFECT OSI_BIT(6) -#define OSI_OPER_DIS_PERFECT OSI_BIT(7) -#define OSI_OPER_ADDR_UPDATE OSI_BIT(8) -#define OSI_OPER_ADDR_DEL OSI_BIT(9) - -#define OSI_PAUSE_FRAMES_DISABLE 1U -#define OSI_PFT_MATCH 0U -#define OSI_SOURCE_MATCH 0U -#define OSI_SA_MATCH 1U - -#define OSI_SPEED_10 10 -#define OSI_SPEED_100 100 -#define OSI_SPEED_1000 1000 -#define OSI_SPEED_2500 2500 -#define OSI_SPEED_5000 5000 -#define OSI_SPEED_10000 10000 - -#define TEN_POWER_9 0x3B9ACA00U -#define TWO_POWER_32 0x100000000ULL -#define TWO_POWER_31 0x80000000U -/* MDIO clause 45 bit */ -#define OSI_MII_ADDR_C45 OSI_BIT(30) -/** @} */ - -/** - * @brief Ethernet PHY Interface Modes - */ -#define OSI_XFI_MODE_10G 0U -#define OSI_XFI_MODE_5G 1U -#define OSI_USXGMII_MODE_10G 2U -#define OSI_USXGMII_MODE_5G 3U - -/** - * @addtogroup PTP-offload PTP offload defines - * @{ - */ -#define OSI_PTP_SNAP_ORDINARY 0U -#define OSI_PTP_SNAP_TRANSPORT 1U -#define OSI_PTP_SNAP_P2P 3U -#define OSI_PTP_MAX_PORTID 0xFFFFU -#define OSI_PTP_MAX_DOMAIN 0xFFU - -/** - * @addtogroup IOCTL OPS MACROS - * - * @brief IOCTL OPS for runtime commands - * @{ - */ -#define OSI_CMD_MDC_CONFIG 1U -#define OSI_CMD_RESTORE_REGISTER 2U -#define OSI_CMD_L3L4_FILTER 3U -#define OSI_CMD_POLL_FOR_MAC_RST 4U -#define OSI_CMD_START_MAC 5U -#define OSI_CMD_STOP_MAC 6U -#define OSI_CMD_COMMON_ISR 7U -#define OSI_CMD_PAD_CALIBRATION 8U -#define OSI_CMD_READ_MMC 9U -#define OSI_CMD_GET_MAC_VER 10U -#define OSI_CMD_VALIDATE_CORE_REG 11U -#define OSI_CMD_RESET_MMC 12U -#define OSI_CMD_SAVE_REGISTER 13U -#define OSI_CMD_MAC_LB 14U -#define OSI_CMD_FLOW_CTRL 15U -#define OSI_CMD_SET_MODE 16U -#define OSI_CMD_SET_SPEED 17U -#define OSI_CMD_L2_FILTER 18U -#define OSI_CMD_RXCSUM_OFFLOAD 19U -#define OSI_CMD_ADJ_FREQ 20U -#define OSI_CMD_ADJ_TIME 21U -#define OSI_CMD_CONFIG_PTP 22U -#define OSI_CMD_GET_AVB 23U -#define OSI_CMD_SET_AVB 24U -#define OSI_CMD_CONFIG_RX_CRC_CHECK 25U -#define OSI_CMD_UPDATE_VLAN_ID 26U -#define OSI_CMD_CONFIG_TXSTATUS 27U -#define OSI_CMD_GET_HW_FEAT 28U -#define OSI_CMD_CONFIG_FW_ERR 29U -#define OSI_CMD_ARP_OFFLOAD 30U -#define OSI_CMD_VLAN_FILTER 31U -#define OSI_CMD_CONFIG_EEE 32U -#define OSI_CMD_SET_SYSTOHW_TIME 33U -#define OSI_CMD_CONFIG_PTP_OFFLOAD 34U -#define OSI_CMD_PTP_RXQ_ROUTE 35U -#define OSI_CMD_CONFIG_FRP 36U -#define OSI_CMD_CONFIG_RSS 37U -#define OSI_CMD_CONFIG_EST 38U -#define OSI_CMD_CONFIG_FPE 39U -#define OSI_CMD_READ_REG 40U -#define OSI_CMD_WRITE_REG 41U -#define OSI_CMD_GET_TX_TS 42U -#define OSI_CMD_FREE_TS 43U -#ifdef OSI_DEBUG -#define OSI_CMD_REG_DUMP 44U -#define OSI_CMD_STRUCTS_DUMP 45U -#endif /* OSI_DEBUG */ -#define OSI_CMD_CAP_TSC_PTP 46U -#define OSI_CMD_MAC_MTU 47U -#define OSI_CMD_CONF_M2M_TS 48U -#ifdef MACSEC_SUPPORT -#define OSI_CMD_READ_MACSEC_REG 49U -#define OSI_CMD_WRITE_MACSEC_REG 50U -#endif /* MACSEC_SUPPORT */ -#ifdef HSI_SUPPORT -#define OSI_CMD_HSI_CONFIGURE 51U -#endif -/** @} */ - -/** - * @brief OSI error macro definition, - * @param[in] priv: OSD private data OR NULL - * @param[in] type: error type - * @param[in] err: error string - * @param[in] loga: error additional information - */ -#define OSI_CORE_ERR(priv, type, err, loga) \ -{ \ - osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_ERR, type, err, loga);\ -} - -/** - * @brief OSI info macro definition - * @param[in] priv: OSD private data OR NULL - * @param[in] type: error type - * @param[in] err: error string - * @param[in] loga: error additional information - */ -#define OSI_CORE_INFO(priv, type, err, loga) \ -{ \ - osi_core->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_INFO, type, err, loga); \ -} - -#define VLAN_NUM_VID 4096U -#define OSI_VLAN_ACTION_ADD OSI_BIT(31) -#define OSI_VLAN_ACTION_DEL 0x0U -#define OSI_RXQ_ROUTE_PTP 0U -#define OSI_DELAY_1000US 1000U -#define OSI_DELAY_1US 1U -/** - * @addtogroup RSS related information - * - * @brief RSS hash key and table size. - * @{ - */ -#define OSI_RSS_HASH_KEY_SIZE 40U -#define OSI_RSS_MAX_TABLE_SIZE 128U -/** @} */ - -/** - * @addtogroup PTP related information - * - * @brief PTP SSINC values - * @{ - */ -#define OSI_PTP_SSINC_16 16U -#define OSI_PTP_SSINC_4 4U -#define OSI_PTP_SSINC_6 6U -/** @} */ - -/** - * @addtogroup Flexible Receive Parser related information - * - * @brief Flexible Receive Parser commands, table size and other defines - * @{ - */ -#define OSI_FRP_MAX_ENTRY 256U -#define OSI_FRP_OFFSET_MAX 64U -/* FRP Command types */ -#define OSI_FRP_CMD_ADD 0U -#define OSI_FRP_CMD_UPDATE 1U -#define OSI_FRP_CMD_DEL 2U -#define OSI_FRP_CMD_MAX 3U -/* FRP Filter mode defines */ -#define OSI_FRP_MODE_ROUTE 0U -#define OSI_FRP_MODE_DROP 1U -#define OSI_FRP_MODE_BYPASS 2U -#define OSI_FRP_MODE_LINK 3U -#define OSI_FRP_MODE_IM_ROUTE 4U -#define OSI_FRP_MODE_IM_DROP 5U -#define OSI_FRP_MODE_IM_BYPASS 6U -#define OSI_FRP_MODE_IM_LINK 7U -#define OSI_FRP_MODE_MAX 8U -/* Match data defines */ -#define OSI_FRP_MATCH_DATA_MAX 12U -#define OSI_FRP_MATCH_NORMAL 0U -#define OSI_FRP_MATCH_L2_DA 1U -#define OSI_FRP_MATCH_L2_SA 2U -#define OSI_FRP_MATCH_L3_SIP 3U -#define OSI_FRP_MATCH_L3_DIP 4U -#define OSI_FRP_MATCH_L4_S_UPORT 5U -#define OSI_FRP_MATCH_L4_D_UPORT 6U -#define OSI_FRP_MATCH_L4_S_TPORT 7U -#define OSI_FRP_MATCH_L4_D_TPORT 8U -#define OSI_FRP_MATCH_VLAN 9U -#define OSI_FRP_MATCH_MAX 10U -/** @} */ - -#ifdef HSI_SUPPORT -/** - * @addtogroup hsi_err_code_idx - * - * @brief data index for hsi_err_code array - * @{ - */ -#define REPORTER_IDX 2U - -#define UE_IDX 0U -#define CE_IDX 1U -#define RX_CRC_ERR_IDX 2U -#define TX_FRAME_ERR_IDX 3U -#define RX_CSUM_ERR_IDX 4U -#define AUTONEG_ERR_IDX 5U - -#define MACSEC_RX_CRC_ERR_IDX 0U -#define MACSEC_TX_CRC_ERR_IDX 1U -#define MACSEC_RX_ICV_ERR_IDX 2U -/** @} */ - -extern nveu32_t hsi_err_code[][3]; - -/** - * @addtogroup HSI_TIME_THRESHOLD - * - * @brief HSI time threshold to report error in ms - * @{ - */ -#define OSI_HSI_ERR_TIME_THRESHOLD_DEFAULT 3000U -#define OSI_HSI_ERR_TIME_THRESHOLD_MIN 1000U -#define OSI_HSI_ERR_TIME_THRESHOLD_MAX 60000U -/** @} */ - -/** - * @brief HSI error count threshold to report error - */ -#define OSI_HSI_ERR_COUNT_THRESHOLD 1000U - -/** - * @brief Maximum number of different mac error code - */ -#define HSI_MAX_MAC_ERROR_CODE 6U - -/** - * @brief Maximum number of different macsec error code - */ -#define HSI_MAX_MACSEC_ERROR_CODE 3U - -/** - * @addtogroup HSI_SW_ERR_CODE - * - * @brief software defined error code - * @{ - */ -#define OSI_INBOUND_BUS_CRC_ERR 0x1001U -#define OSI_TX_FRAME_ERR 0x1002U -#define OSI_RECEIVE_CHECKSUM_ERR 0x1003U -#define OSI_PCS_AUTONEG_ERR 0x1004U -#define OSI_MACSEC_RX_CRC_ERR 0x1005U -#define OSI_MACSEC_TX_CRC_ERR 0x1006U -#define OSI_MACSEC_RX_ICV_ERR 0x1007U - -/** @} */ -#endif - -struct osi_core_priv_data; - -/** - * @brief OSI core structure for filters - */ -struct osi_filter { - /** indicates operation needs to perform. refer to OSI_OPER_* */ - nveu32_t oper_mode; - /** Indicates the index of the filter to be modified. - * Filter index must be between 0 - 127 */ - nveu32_t index; - /** Ethernet MAC address to be added */ - nveu8_t mac_address[OSI_ETH_ALEN]; - /** Indicates dma channel routing enable(1) disable (0) */ - nveu32_t dma_routing; - /** indicates dma channel number to program */ - nveu32_t dma_chan; - /** filter will not consider byte in comparison - * Bit 5: MAC_Address${i}_High[15:8] - * Bit 4: MAC_Address${i}_High[7:0] - * Bit 3: MAC_Address${i}_Low[31:24] - * .. - * Bit 0: MAC_Address${i}_Low[7:0] */ - nveu32_t addr_mask; - /** src_dest: SA(1) or DA(0) */ - nveu32_t src_dest; - /** indicates one hot encoded DMA receive channels to program */ - nveu32_t dma_chansel; -}; - -/** - * @brief OSI core structure for RXQ route - */ -struct osi_rxq_route { -#define OSI_RXQ_ROUTE_PTP 0U - /** Indicates RX routing type OSI_RXQ_ROUTE_* */ - unsigned int route_type; - /** RXQ routing enable(1) disable (0) */ - unsigned int enable; - /** RX queue index */ - unsigned int idx; -}; - -/** - * @brief L3/L4 filter function dependent parameter - */ -struct osi_l3_l4_filter { - /** Indicates the index of the filter to be modified. - * Filter index must be between 0 - 7 */ - nveu32_t filter_no; - /** filter enable(1) or disable(0) */ - nveu32_t filter_enb_dis; - /** source(0) or destination(1) */ - nveu32_t src_dst_addr_match; - /** perfect(0) or inverse(1) */ - nveu32_t perfect_inverse_match; - /** ipv4 address */ - nveu8_t ip4_addr[4]; - /** ipv6 address */ - nveu16_t ip6_addr[8]; - /** Port number */ - nveu16_t port_no; -}; - -/** - * @brief struct osi_hw_features - MAC HW supported features. - */ -struct osi_hw_features { - /** It is set to 1 when 10/100 Mbps is selected as the Mode of - * Operation */ - nveu32_t mii_sel; - /** It is set to 1 when the RGMII Interface option is selected */ - nveu32_t rgmii_sel; - /** It is set to 1 when the RMII Interface option is selected */ - nveu32_t rmii_sel; - /** It sets to 1 when 1000 Mbps is selected as the Mode of Operation */ - nveu32_t gmii_sel; - /** It sets to 1 when the half-duplex mode is selected */ - nveu32_t hd_sel; - /** It sets to 1 when the TBI, SGMII, or RTBI PHY interface - * option is selected */ - nveu32_t pcs_sel; - /** It sets to 1 when the Enable VLAN Hash Table Based Filtering - * option is selected */ - nveu32_t vlan_hash_en; - /** It sets to 1 when the Enable Station Management (MDIO Interface) - * option is selected */ - nveu32_t sma_sel; - /** It sets to 1 when the Enable Remote Wake-Up Packet Detection - * option is selected */ - nveu32_t rwk_sel; - /** It sets to 1 when the Enable Magic Packet Detection option is - * selected */ - nveu32_t mgk_sel; - /** It sets to 1 when the Enable MAC Management Counters (MMC) option - * is selected */ - nveu32_t mmc_sel; - /** It sets to 1 when the Enable IPv4 ARP Offload option is selected */ - nveu32_t arp_offld_en; - /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option - * is selected */ - nveu32_t ts_sel; - /** It sets to 1 when the Enable Energy Efficient Ethernet (EEE) option - * is selected */ - nveu32_t eee_sel; - /** It sets to 1 when the Enable Transmit TCP/IP Checksum Insertion - * option is selected */ - nveu32_t tx_coe_sel; - /** It sets to 1 when the Enable Receive TCP/IP Checksum Check option - * is selected */ - nveu32_t rx_coe_sel; - /** It sets to 1 when the Enable Additional 1-31 MAC Address Registers - * option is selected */ - nveu32_t mac_addr_sel; - /** It sets to 1 when the Enable Additional 32-63 MAC Address Registers - * option is selected */ - nveu32_t mac_addr32_sel; - /** It sets to 1 when the Enable Additional 64-127 MAC Address Registers - * option is selected */ - nveu32_t mac_addr64_sel; - /** It sets to 1 when the Enable IEEE 1588 Timestamp Support option - * is selected */ - nveu32_t tsstssel; - /** It sets to 1 when the Enable SA and VLAN Insertion on Tx option - * is selected */ - nveu32_t sa_vlan_ins; - /** Active PHY Selected - * When you have multiple PHY interfaces in your configuration, - * this field indicates the sampled value of phy_intf_sel_i during - * reset de-assertion: - * 000: GMII or MII - * 001: RGMII - * 010: SGMII - * 011: TBI - * 100: RMII - * 101: RTBI - * 110: SMII - * 111: RevMII - * All Others: Reserved */ - nveu32_t act_phy_sel; - /** MTL Receive FIFO Size - * This field contains the configured value of MTL Rx FIFO in bytes - * expressed as Log to base 2 minus 7, that is, Log2(RXFIFO_SIZE) -7: - * 00000: 128 bytes - * 00001: 256 bytes - * 00010: 512 bytes - * 00011: 1,024 bytes - * 00100: 2,048 bytes - * 00101: 4,096 bytes - * 00110: 8,192 bytes - * 00111: 16,384 bytes - * 01000: 32,767 bytes - * 01000: 32 KB - * 01001: 64 KB - * 01010: 128 KB - * 01011: 256 KB - * 01100-11111: Reserved */ - nveu32_t rx_fifo_size; - /** MTL Transmit FIFO Size. - * This field contains the configured value of MTL Tx FIFO in - * bytes expressed as Log to base 2 minus 7, that is, - * Log2(TXFIFO_SIZE) -7: - * 00000: 128 bytes - * 00001: 256 bytes - * 00010: 512 bytes - * 00011: 1,024 bytes - * 00100: 2,048 bytes - * 00101: 4,096 bytes - * 00110: 8,192 bytes - * 00111: 16,384 bytes - * 01000: 32 KB - * 01001: 64 KB - * 01010: 128 KB - * 01011-11111: Reserved */ - nveu32_t tx_fifo_size; - /** It set to 1 when Advance timestamping High Word selected */ - nveu32_t adv_ts_hword; - /** Address Width. - * This field indicates the configured address width: - * 00: 32 - * 01: 40 - * 10: 48 - * 11: Reserved */ - nveu32_t addr_64; - /** It sets to 1 when DCB Feature Enable */ - nveu32_t dcb_en; - /** It sets to 1 when Split Header Feature Enable */ - nveu32_t sph_en; - /** It sets to 1 when TCP Segmentation Offload Enable */ - nveu32_t tso_en; - /** It sets to 1 when DMA debug registers are enabled */ - nveu32_t dma_debug_gen; - /** It sets to 1 if AV Feature Enabled */ - nveu32_t av_sel; - /** It sets to 1 if Receive side AV Feature Enabled */ - nveu32_t rav_sel; - /** This field indicates the size of the hash table: - * 00: No hash table - * 01: 64 - * 10: 128 - * 11: 256 */ - nveu32_t hash_tbl_sz; - /** This field indicates the total number of L3 or L4 filters: - * 0000: No L3 or L4 Filter - * 0001: 1 L3 or L4 Filter - * 0010: 2 L3 or L4 Filters - * .. - * 1000: 8 L3 or L4 */ - nveu32_t l3l4_filter_num; - /** It holds number of MTL Receive Queues */ - nveu32_t rx_q_cnt; - /** It holds number of MTL Transmit Queues */ - nveu32_t tx_q_cnt; - /** It holds number of DMA Receive channels */ - nveu32_t rx_ch_cnt; - /** This field indicates the number of DMA Transmit channels: - * 0000: 1 DMA Tx Channel - * 0001: 2 DMA Tx Channels - * .. - * 0111: 8 DMA Tx */ - nveu32_t tx_ch_cnt; - /** This field indicates the number of PPS outputs: - * 000: No PPS output - * 001: 1 PPS output - * 010: 2 PPS outputs - * 011: 3 PPS outputs - * 100: 4 PPS outputs - * 101-111: Reserved */ - nveu32_t pps_out_num; - /** Number of Auxiliary Snapshot Inputs - * This field indicates the number of auxiliary snapshot inputs: - * 000: No auxiliary input - * 001: 1 auxiliary input - * 010: 2 auxiliary inputs - * 011: 3 auxiliary inputs - * 100: 4 auxiliary inputs - * 101-111: Reserved */ - nveu32_t aux_snap_num; - /** VxLAN/NVGRE Support */ - nveu32_t vxn; - /** Enhanced DMA. - * This bit is set to 1 when the "Enhanced DMA" option is - * selected. */ - nveu32_t edma; - /** Different Descriptor Cache - * When set to 1, then EDMA mode Separate Memory is - * selected for the Descriptor Cache.*/ - nveu32_t ediffc; - /** PFC Enable - * This bit is set to 1 when the Enable PFC Feature is selected */ - nveu32_t pfc_en; - /** One-Step Timestamping Enable */ - nveu32_t ost_en; - /** PTO Offload Enable */ - nveu32_t pto_en; - /** Receive Side Scaling Enable */ - nveu32_t rss_en; - /** Number of Traffic Classes */ - nveu32_t num_tc; - /** Number of Extended VLAN Tag Filters Enabled */ - nveu32_t num_vlan_filters; - /** Supported Flexible Receive Parser. - * This bit is set to 1 when the Enable Flexible Programmable - * Receive Parser option is selected */ - nveu32_t frp_sel; - /** Queue/Channel based VLAN tag insertion on Tx Enable - * This bit is set to 1 when the Enable Queue/Channel based - * VLAN tag insertion on Tx Feature is selected. */ - nveu32_t cbti_sel; - /** Supported Parallel Instruction Processor Engines (PIPEs) - * This field indicates the maximum number of Instruction - * Processors supported by flexible receive parser. */ - nveu32_t num_frp_pipes; - /** One Step for PTP over UDP/IP Feature Enable - * This bit is set to 1 when the Enable One step timestamp for - * PTP over UDP/IP feature is selected */ - nveu32_t ost_over_udp; - /** Supported Flexible Receive Parser Parsable Bytes - * This field indicates the supported Max Number of bytes of the - * packet data to be Parsed by Flexible Receive Parser */ - nveu32_t max_frp_bytes; - /** Supported Flexible Receive Parser Instructions - * This field indicates the Max Number of Parser Instructions - * supported by Flexible Receive Parser */ - nveu32_t max_frp_entries; - /** Double VLAN Processing Enabled - * This bit is set to 1 when the Enable Double VLAN Processing - * feature is selected */ - nveu32_t double_vlan_en; - /** Automotive Safety Package - * Following are the encoding for the different Safety features - * Values: - * 0x0 (NONE): No Safety features selected - * 0x1 (ECC_ONLY): Only "ECC protection for external - * memory" feature is selected - * 0x2 (AS_NPPE): All the Automotive Safety features are - * selected without the "Parity Port Enable for external interface" - * feature - * 0x3 (AS_PPE): All the Automotive Safety features are - * selected with the "Parity Port Enable for external interface" - * feature */ - nveu32_t auto_safety_pkg; - /** Tx Timestamp FIFO Depth - * This value indicates the depth of the Tx Timestamp FIFO - * 3'b000: Reserved - * 3'b001: 1 - * 3'b010: 2 - * 3'b011: 4 - * 3'b100: 8 - * 3'b101: 16 - * 3'b110: Reserved - * 3'b111: Reserved */ - nveu32_t tts_fifo_depth; - /** Enhancements to Scheduling Traffic Enable - * This bit is set to 1 when the Enable Enhancements to - * Scheduling Traffic feature is selected. - * Values: - * 0x0 (INACTIVE): Enable Enhancements to Scheduling - * Traffic feature is not selected - * 0x1 (ACTIVE): Enable Enhancements to Scheduling - * Traffic feature is selected */ - nveu32_t est_sel; - /** Depth of the Gate Control List - * This field indicates the depth of Gate Control list expressed as - * Log2(DWCXG_GCL_DEP)-5 - * Values: - * 0x0 (NODEPTH): No Depth configured - * 0x1 (DEPTH64): 64 - * 0x2 (DEPTH128): 128 - * 0x3 (DEPTH256): 256 - * 0x4 (DEPTH512): 512 - * 0x5 (DEPTH1024): 1024 - * 0x6 (RSVD): Reserved */ - nveu32_t gcl_depth; - /** Width of the Time Interval field in the Gate Control List - * This field indicates the width of the Configured Time Interval - * Field - * Values: - * 0x0 (NOWIDTH): Width not configured - * 0x1 (WIDTH16): 16 - * 0x2 (WIDTH20): 20 - * 0x3 (WIDTH24): 24 */ - nveu32_t gcl_width; - /** Frame Preemption Enable - * This bit is set to 1 when the Enable Frame preemption feature - * is selected. - * Values: - * 0x0 (INACTIVE): Frame Preemption Enable feature is not - * selected - * 0x1 (ACTIVE): Frame Preemption Enable feature is - * selected */ - nveu32_t fpe_sel; - /** Time Based Scheduling Enable - * This bit is set to 1 when the Time Based Scheduling feature is - * selected. - * Values: - * 0x0 (INACTIVE): Time Based Scheduling Enable feature is - * not selected - * 0x1 (ACTIVE): Time Based Scheduling Enable feature is - * selected */ - nveu32_t tbs_sel; - /** The number of DMA channels enabled for TBS (starting from - * the highest Tx Channel in descending order) - * This field provides the number of DMA channels enabled for - * TBS (starting from the highest Tx Channel in descending - * order): - * 0000: 1 DMA Tx Channel enabled for TBS - * 0001: 2 DMA Tx Channels enabled for TBS - * 0010: 3 DMA Tx Channels enabled for TBS - * ... - * 1111: 16 DMA Tx Channels enabled for TBS */ - nveu32_t num_tbs_ch; -}; - -#ifndef OSI_STRIPPED_LIB -/** - * @brief Vlan filter Function dependent parameter - */ -struct osi_vlan_filter { - /** vlan filter enable(1) or disable(0) */ - nveu32_t filter_enb_dis; - /** perfect(0) or hash(1) */ - nveu32_t perfect_hash; - /** perfect(0) or inverse(1) */ - nveu32_t perfect_inverse_match; -}; - -/** - * @brief FRP Instruction configuration structure - */ -struct osi_core_frp_data { - /* Entry Match Data */ - unsigned int match_data; - /* Entry Match Enable mask */ - unsigned int match_en; - /* Entry Accept frame flag */ - unsigned char accept_frame; - /* Entry Reject Frame flag */ - unsigned char reject_frame; - /* Entry Inverse match flag */ - unsigned char inverse_match; - /* Entry Next Instruction Control match flag */ - unsigned char next_ins_ctrl; - /* Entry Frame offset in the packet data */ - unsigned char frame_offset; - /* Entry OK Index - Next Instruction */ - unsigned char ok_index; - /* Entry DMA Channel selection (1-bit for each channel) */ - unsigned int dma_chsel; -}; - -/** - * @brief FRP command structure for OSD to OSI - */ -struct osi_core_frp_cmd { - /* FRP Command type */ - unsigned int cmd; - /* OSD FRP ID */ - int frp_id; - /* OSD match data type */ - unsigned char match_type; - /* OSD match data */ - unsigned char match[OSI_FRP_MATCH_DATA_MAX]; - /* OSD match data length */ - unsigned char match_length; - /* OSD Offset */ - unsigned char offset; - /* OSD FRP filter mode flag */ - unsigned char filter_mode; - /* OSD FRP Link ID */ - int next_frp_id; - /* OSD DMA Channel Selection */ - unsigned int dma_sel; -}; - -/** - * @brief FRP Instruction table entry configuration structure - */ -struct osi_core_frp_entry { - /* FRP ID */ - int frp_id; - /* FRP Entry data structure */ - struct osi_core_frp_data data; -}; - -/** - * @brief L2 filter function dependent parameter - */ -struct osi_l2_da_filter { - /** perfect(0) or hash(1) */ - nveu32_t perfect_hash; - /** perfect(0) or inverse(1) */ - nveu32_t perfect_inverse_match; -}; - -/** - * @brief OSI Core avb data structure per queue. - */ -struct osi_core_avb_algorithm { - /** TX Queue/TC index */ - nveu32_t qindex; - /** CBS Algorithm enable(1) or disable(0) */ - nveu32_t algo; - /** When this bit is set, the accumulated credit parameter in the - * credit-based shaper algorithm logic is not reset to zero when - * there is positive credit and no packet to transmit in Channel. - * - * Expected values are enable(1) or disable(0) */ - nveu32_t credit_control; - /** idleSlopeCredit value required for CBS */ - nveu32_t idle_slope; - /** sendSlopeCredit value required for CBS */ - nveu32_t send_slope; - /** hiCredit value required for CBS */ - nveu32_t hi_credit; - /** lowCredit value required for CBS */ - nveu32_t low_credit; - /** Transmit queue operating mode - * - * 00: disable - * - * 01: avb - * - * 10: enable */ - nveu32_t oper_mode; - /** TC index */ - unsigned int tcindex; -}; -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief struct ptp_offload_param - Parameter to support PTP offload. - */ -struct osi_pto_config { - /** enable(0) / disable(1) */ - unsigned int en_dis; - /** Flag for Master mode. - * OSI_ENABLE for master OSI_DISABLE for slave */ - unsigned int master; - /** Flag to Select PTP packets for Taking Snapshots */ - unsigned int snap_type; - /** ptp domain */ - unsigned int domain_num; - /** The PTP Offload function qualifies received PTP - * packet with unicast Destination address - * 0 - only multicast, 1 - unicast and multicast */ - unsigned int mc_uc; - /** Port identification */ - unsigned int portid; -}; - -/** - * @brief OSI Core EST structure - */ -struct osi_est_config { - /** enable/disable */ - unsigned int en_dis; - /** 64 bit base time register - * if both vlaues are 0, take ptp time to avoid BTRE - * index 0 for nsec, index 1 for sec - */ - unsigned int btr[2]; - /** 64 bit base time offset index 0 for nsec, index 1 for sec */ - unsigned int btr_offset[2]; - /** 40 bit cycle time register, index 0 for nsec, index 1 for sec */ - unsigned int ctr[2]; - /** Configured Time Interval width + 7 bit extension register */ - unsigned int ter; - /** size of the gate control list */ - unsigned int llr; - /** data array 8 bit gate op + 24 execution time - * MGBE HW support GCL depth 256 */ - unsigned int gcl[OSI_GCL_SIZE_256]; -}; - -/** - * @brief OSI Core FPE structure - */ -struct osi_fpe_config { - /** Queue Mask 1 preemption 0- express bit representation */ - unsigned int tx_queue_preemption_enable; - /** RQ for all preemptable packets which are not filtered - * based on user priority or SA-DA - */ - unsigned int rq; -}; - -/** - * @brief OSI Core TSN error stats structure - */ -struct osi_tsn_stats { - /** Constant Gate Control Error */ - unsigned long const_gate_ctr_err; - /** Head-Of-Line Blocking due to Scheduling */ - unsigned long head_of_line_blk_sch; - /** Per TC Schedule Error */ - unsigned long hlbs_q[OSI_MAX_TC_NUM]; - /** Head-Of-Line Blocking due to Frame Size */ - unsigned long head_of_line_blk_frm; - /** Per TC Frame Size Error */ - unsigned long hlbf_q[OSI_MAX_TC_NUM]; - /** BTR Error */ - unsigned long base_time_reg_err; - /** Switch to Software Owned List Complete */ - unsigned long sw_own_list_complete; -}; - -/** - * @brief PTP configuration structure - */ -struct osi_ptp_config { - /** PTP filter parameters bit fields. - * - * Enable Timestamp, Fine Timestamp, 1 nanosecond accuracy - * are enabled by default. - * - * Need to set below bit fields accordingly as per the requirements. - * - * Enable Timestamp for All Packets OSI_BIT(8) - * - * Enable PTP Packet Processing for Version 2 Format OSI_BIT(10) - * - * Enable Processing of PTP over Ethernet Packets OSI_BIT(11) - * - * Enable Processing of PTP Packets Sent over IPv6-UDP OSI_BIT(12) - * - * Enable Processing of PTP Packets Sent over IPv4-UDP OSI_BIT(13) - * - * Enable Timestamp Snapshot for Event Messages OSI_BIT(14) - * - * Enable Snapshot for Messages Relevant to Master OSI_BIT(15) - * - * Select PTP packets for Taking Snapshots OSI_BIT(16) - * - * Select PTP packets for Taking Snapshots OSI_BIT(17) - * - * Select PTP packets for Taking Snapshots (OSI_BIT(16) + OSI_BIT(17)) - * - * AV 802.1AS Mode Enable OSI_BIT(28) - * - * if ptp_filter is set to Zero then Time stamping is disabled */ - nveu32_t ptp_filter; - /** seconds to be updated to MAC */ - nveu32_t sec; - /** nano seconds to be updated to MAC */ - nveu32_t nsec; - /** PTP reference clock read from DT */ - nveu32_t ptp_ref_clk_rate; - /** Use one nsec accuracy (need to set 1) */ - nveu32_t one_nsec_accuracy; - /** PTP system clock which is 62500000Hz */ - nveu32_t ptp_clock; - /** PTP Packets RX Queue.*/ - nveu32_t ptp_rx_queue; -}; - -/** - * @brief osi_core_rss - Struture used to store RSS Hash key and table - * information. - */ -struct osi_core_rss { - /** Flag to represent to enable RSS or not */ - unsigned int enable; - /** Array for storing RSS Hash key */ - unsigned char key[OSI_RSS_HASH_KEY_SIZE]; - /** Array for storing RSS Hash table */ - unsigned int table[OSI_RSS_MAX_TABLE_SIZE]; -}; - -/** - * @brief osi_core_ptp_tsc_data - Struture used to store TSC and PTP time - * information. - */ -struct osi_core_ptp_tsc_data { - /** high bits of MAC */ - nveu32_t ptp_high_bits; - /** low bits of MAC */ - nveu32_t ptp_low_bits; - /** high bits of TSC */ - nveu32_t tsc_high_bits; - /** low bits of TSC */ - nveu32_t tsc_low_bits; -}; - -/** - * @brief Max num of MAC core registers to backup. It should be max of or >= - * (EQOS_MAX_BAK_IDX=380, coreX,...etc) backup registers. - */ -#define CORE_MAX_BAK_IDX 700U - -/** - * @brief core_backup - Struct used to store backup of core HW registers. - */ -struct core_backup { - /** Array of reg MMIO addresses (base of MAC + offset of reg) */ - void *reg_addr[CORE_MAX_BAK_IDX]; - /** Array of value stored in each corresponding register */ - nveu32_t reg_val[CORE_MAX_BAK_IDX]; -}; - -/** - * @brief OSI VM IRQ data - */ -struct osi_vm_irq_data { - /** Number of VM channels per VM IRQ */ - nveu32_t num_vm_chans; - /** VM/OS number to be used */ - nveu32_t vm_num; - /** Array of VM channel list */ - nveu32_t vm_chans[OSI_MGBE_MAX_NUM_CHANS]; -}; - -/** - *@brief OSD Core callbacks - */ -struct osd_core_ops { - /** padctrl rx pin disable/enable callback */ - int (*padctrl_mii_rx_pins)(void *priv, nveu32_t enable); - /** logging callback */ - void (*ops_log)(void *priv, const nve8_t *func, nveu32_t line, - nveu32_t level, nveu32_t type, const nve8_t *err, - nveul64_t loga); - /** udelay callback */ - void (*udelay)(nveu64_t usec); - /** usleep range callback */ - void (*usleep_range)(nveu64_t umin, nveu64_t umax); - /** msleep callback */ - void (*msleep)(nveu32_t msec); - /** ivcsend callback*/ - nve32_t (*ivc_send)(void *priv, struct ivc_msg_common *ivc, - nveu32_t len); -#ifdef MACSEC_SUPPORT - /** Program macsec key table through Trust Zone callback */ - nve32_t (*macsec_tz_kt_config)(void *priv, unsigned char cmd, - void *const kt_config, - void *const genl_info); -#endif /* MACSEC_SUPPORT */ -#ifdef OSI_DEBUG - /**.printf function callback */ - void (*printf)(struct osi_core_priv_data *osi_core, - nveu32_t type, - const char *fmt, ...); -#endif -}; - -#ifdef MACSEC_SUPPORT -/** - * @brief MACSEC secure channel basic information - */ -struct osi_macsec_sc_info { - /** Secure channel identifier */ - nveu8_t sci[OSI_SCI_LEN]; - /** Secure association key */ - nveu8_t sak[OSI_KEY_LEN_128]; -#ifdef MACSEC_KEY_PROGRAM - /** Secure association key */ - nveu8_t hkey[OSI_KEY_LEN_128]; -#endif /* MACSEC_KEY_PROGRAM */ - /** current AN */ - nveu8_t curr_an; - /** Next PN to use for the current AN */ - nveu32_t next_pn; - /** Lowest PN to use for the current AN */ - nveu32_t lowest_pn; - /** bitmap of valid AN */ - nveu32_t an_valid; - /** PN window */ - nveu32_t pn_window; - /** SC LUT index */ - nveu32_t sc_idx_start; - /** flags - encoding various states of SA */ - nveu32_t flags; -}; - -/** - * @brief MACSEC HW controller LUT's global status - */ -struct osi_macsec_lut_status { - /** List of max SC's supported */ - struct osi_macsec_sc_info sc_info[OSI_MAX_NUM_SC]; - /** next available BYP LUT index */ - nveu16_t next_byp_idx; - /** number of active SCs */ - nveu32_t num_of_sc_used; -}; - -/** - * @brief MACsec interrupt stats structure. - */ -struct osi_macsec_irq_stats { - /** Tx debug buffer capture done */ - nveu64_t tx_dbg_capture_done; - /** Tx MTU check failed */ - nveu64_t tx_mtu_check_fail; - /** Tx MAC CRC err */ - nveu64_t tx_mac_crc_error; - /** Tx SC AN not valid */ - nveu64_t tx_sc_an_not_valid; - /** Tx AES GCM buffer overflow */ - nveu64_t tx_aes_gcm_buf_ovf; - /** Tx LUT lookup miss */ - nveu64_t tx_lkup_miss; - /** Tx uninitialized key slot */ - nveu64_t tx_uninit_key_slot; - /** Tx PN threshold reached */ - nveu64_t tx_pn_threshold; - /** Tx PN exhausted */ - nveu64_t tx_pn_exhausted; - /** Tx debug buffer capture done */ - nveu64_t rx_dbg_capture_done; - /** Rx ICV error threshold */ - nveu64_t rx_icv_err_threshold; - /** Rx replay error */ - nveu64_t rx_replay_error; - /** Rx MTU check failed */ - nveu64_t rx_mtu_check_fail; - /** Rx MAC CRC err */ - nveu64_t rx_mac_crc_error; - /** Rx AES GCM buffer overflow */ - nveu64_t rx_aes_gcm_buf_ovf; - /** Rx LUT lookup miss */ - nveu64_t rx_lkup_miss; - /** Rx uninitialized key slot */ - nveu64_t rx_uninit_key_slot; - /** Rx PN exhausted */ - nveu64_t rx_pn_exhausted; - /** Secure reg violation */ - nveu64_t secure_reg_viol; -}; -#endif /* MACSEC_SUPPORT */ - -/** - * @brief Core time stamp data strcuture - */ -struct osi_core_tx_ts { - /** Pointer to next item in the link */ - struct osi_core_tx_ts *next; - /** Pointer to prev item in the link */ - struct osi_core_tx_ts *prev; - /** Packet ID for corresponding timestamp */ - nveu32_t pkt_id; - /** Time in seconds */ - nveu32_t sec; - /** Time in nano seconds */ - nveu32_t nsec; - /** Variable which says if pkt_id is in use or not */ - nveu32_t in_use; -}; - -/** - * @brief OSI Core data structure for runtime commands. - */ -struct osi_ioctl { - /* runtime command */ - nveu32_t cmd; - /* u32 general argument 1 */ - nveu32_t arg1_u32; - /* u32 general argument 2 */ - nveu32_t arg2_u32; - /* u32 general argument 3 */ - nveu32_t arg3_u32; - /* u32 general argument 4 */ - nveu32_t arg4_u32; - /* u64 general argument 5 */ - nveul64_t arg5_u64; - /* s32 general argument 6 */ - nve32_t arg6_32; - /* u8 string pointer general argument 7 for string */ - nveu8_t *arg7_u8_p; - /* s64 general argument 8 */ - nvel64_t arg8_64; - /* L2 filter structure */ - struct osi_filter l2_filter; - /*l3_l4 filter structure */ - struct osi_l3_l4_filter l3l4_filter; - /* HW feature structure */ - struct osi_hw_features hw_feat; -#ifndef OSI_STRIPPED_LIB - /* AVB structure */ - struct osi_core_avb_algorithm avb; - /* VLAN filter structure */ - struct osi_vlan_filter vlan_filter; -#endif /* !OSI_STRIPPED_LIB */ - /* PTP offload config structure*/ - struct osi_pto_config pto_config; - /* RXQ route structure */ - struct osi_rxq_route rxq_route; - /* FRP structure */ - struct osi_core_frp_cmd frp_cmd; - /* EST structure */ - struct osi_est_config est; - /* FRP structure */ - struct osi_fpe_config fpe; - /** PTP configuration settings */ - struct osi_ptp_config ptp_config; - /** TX Timestamp structure */ - struct osi_core_tx_ts tx_ts; - /** PTP TSC data */ - struct osi_core_ptp_tsc_data ptp_tsc; -}; - -/** - * @brief core_padctrl - Struct used to eqos padctrl details. - */ -struct core_padctrl { - /** Memory mapped base address of eqos padctrl registers */ - void *padctrl_base; - /** EQOS_RD0_0 register offset */ - unsigned int offset_rd0; - /** EQOS_RD1_0 register offset */ - unsigned int offset_rd1; - /** EQOS_RD2_0 register offset */ - unsigned int offset_rd2; - /** EQOS_RD3_0 register offset */ - unsigned int offset_rd3; - /** RX_CTL_0 register offset */ - unsigned int offset_rx_ctl; - /** is pad calibration in progress */ - unsigned int is_pad_cal_in_progress; - /** This flag set/reset using priv ioctl and DT entry */ - unsigned int pad_calibration_enable; -}; - -/** - * @brief OSI CORE packet error stats - */ -struct osi_core_pkt_err_stats { - /** IP Header Error */ - nveu64_t mgbe_ip_header_err; - /** Jabber time out Error */ - nveu64_t mgbe_jabber_timeout_err; - /** Payload Checksum Error */ - nveu64_t mgbe_payload_cs_err; - /** Under Flow Error */ - nveu64_t mgbe_tx_underflow_err; -}; - -#ifdef HSI_SUPPORT -/** - * @brief The OSI Core HSI private data structure. - */ -struct osi_hsi_data { - /** Indicates if HSI feature is enabled */ - nveu32_t enabled; - /** time threshold to report error */ - nveu32_t err_time_threshold; - /** error count threshold to report error */ - nveu32_t err_count_threshold; - /** HSI reporter ID */ - nveu32_t reporter_id; - /** HSI error codes */ - nveu32_t err_code[HSI_MAX_MAC_ERROR_CODE]; - /** HSI MAC report count threshold based error */ - nveu32_t report_count_err[HSI_MAX_MAC_ERROR_CODE]; - /** Indicates if error reporting to FSI is pending */ - nveu32_t report_err; - /** HSI MACSEC error codes */ - nveu32_t macsec_err_code[HSI_MAX_MACSEC_ERROR_CODE]; - /** HSI MACSEC report error based on count threshold */ - nveu32_t macsec_report_count_err[HSI_MAX_MACSEC_ERROR_CODE]; - /** Indicates if error report to FSI is pending for MACSEC*/ - nveu32_t macsec_report_err; - /** RX CRC error report count */ - nveu64_t rx_crc_err_count; - /** RX Checksum error report count */ - nveu64_t rx_checksum_err_count; - /** MACSEC RX CRC error report count */ - nveu64_t macsec_rx_crc_err_count; - /** MACSEC TX CRC error report count */ - nveu64_t macsec_tx_crc_err_count; - /** MACSEC RX ICV error report count */ - nveu64_t macsec_rx_icv_err_count; - /** HW correctable error count */ - nveu64_t ce_count; - /** HW correctable error count hit threshold limit */ - nveu64_t ce_count_threshold; - /** tx frame error count */ - nveu64_t tx_frame_err_count; - /** tx frame error count threshold hit */ - nveu64_t tx_frame_err_threshold; -}; -#endif - -/** - * @brief The OSI Core (MAC & MTL) private data structure. - */ -struct osi_core_priv_data { - /** Memory mapped base address of MAC IP */ - void *base; - /** Memory mapped base address of HV window */ - void *hv_base; - /** Memory mapped base address of DMA window of MAC IP */ - void *dma_base; - /** Memory mapped base address of XPCS IP */ - void *xpcs_base; - /** Memory mapped base address of MACsec IP */ - void *macsec_base; -#ifdef MACSEC_SUPPORT - /** Memory mapped base address of MACsec TZ page */ - void *tz_base; - /** Address of MACsec HW operations structure */ - struct osi_macsec_core_ops *macsec_ops; - /** Instance of macsec interrupt stats structure */ - struct osi_macsec_irq_stats macsec_irq_stats; - /** Instance of macsec HW controller Tx/Rx LUT status */ - struct osi_macsec_lut_status macsec_lut_status[OSI_NUM_CTLR]; - /** macsec mmc counters */ - struct osi_macsec_mmc_counters macsec_mmc; - /** MACSEC enabled state */ - nveu32_t is_macsec_enabled; - /** macsec_fpe_lock used to exclusively configure either macsec - * or fpe config due to bug 3484034 */ - nveu32_t macsec_fpe_lock; - /** FPE HW configuration initited to enable/disable - * 1- FPE HW configuration initiated to enable - * 0- FPE HW configuration initiated to disable */ - unsigned int is_fpe_enabled; -#endif /* MACSEC_SUPPORT */ - /** Pointer to OSD private data structure */ - void *osd; - /** OSD callback ops structure */ - struct osd_core_ops osd_ops; - /** Number of MTL queues enabled in MAC */ - nveu32_t num_mtl_queues; - /** Array of MTL queues */ - nveu32_t mtl_queues[OSI_MGBE_MAX_NUM_CHANS]; - /** List of MTL Rx queue mode that need to be enabled */ - nveu32_t rxq_ctrl[OSI_MGBE_MAX_NUM_CHANS]; - /** Rx MTl Queue mapping based on User Priority field */ - nveu32_t rxq_prio[OSI_MGBE_MAX_NUM_CHANS]; - /** TQ:TC mapping */ - unsigned int tc[OSI_MGBE_MAX_NUM_CHANS]; - /** Residual queue valid with FPE support */ - unsigned int residual_queue; - /** MAC HW type EQOS based on DT compatible */ - nveu32_t mac; - /** MAC version */ - nveu32_t mac_ver; - /** HW supported feature list */ - struct osi_hw_features *hw_feat; - /** MDC clock rate */ - nveu32_t mdc_cr; - /** MTU size */ - nveu32_t mtu; - /** Ethernet MAC address */ - nveu8_t mac_addr[OSI_ETH_ALEN]; - /** DT entry to enable(1) or disable(0) pause frame support */ - nveu32_t pause_frames; - /** Current flow control settings */ - nveu32_t flow_ctrl; - /** PTP configuration settings */ - struct osi_ptp_config ptp_config; - /** Default addend value */ - nveu32_t default_addend; - /** mmc counter structure */ - struct osi_mmc_counters mmc; - /** xtra sw error counters */ - struct osi_xtra_stat_counters xstats; - /** DMA channel selection enable (1) */ - nveu32_t dcs_en; - /** Functional safety config to do periodic read-verify of - * certain safety critical registers */ - void *safety_config; - /** Backup config to save/restore registers during suspend/resume */ - struct core_backup backup_config; - /** VLAN tag stripping enable(1) or disable(0) */ - nveu32_t strip_vlan_tag; - /** L3L4 filter bit bask, set index corresponding bit for - * filter if filter enabled */ - nveu32_t l3l4_filter_bitmask; - /** csr clock is to program LPI 1 us tick timer register. - * Value stored in MHz - */ - nveu32_t csr_clk_speed; - /** Tegra Pre-si platform info */ - nveu32_t pre_si; - /** Flag which decides virtualization is enabled(1) or disabled(0) */ - nveu32_t use_virtualization; - unsigned long vf_bitmap; - /** Array to maintaion VLAN filters */ - unsigned short vid[VLAN_NUM_VID]; - /** Count of number of VLAN filters in vid array */ - unsigned short vlan_filter_cnt; - /** FRP Instruction Table */ - struct osi_core_frp_entry frp_table[OSI_FRP_MAX_ENTRY]; - /** Number of valid Entries in the FRP Instruction Table */ - unsigned int frp_cnt; - /** RSS core structure */ - struct osi_core_rss rss; - /** HW supported feature list */ - struct osi_hw_features *hw_feature; - /** Switch to Software Owned List Complete. - * 1 - Successful and User configured GCL in placed */ - unsigned int est_ready; - /** FPE enabled, verify and respose done with peer device - * 1- Sucessful and can be used between P2P device */ - unsigned int fpe_ready; - /** TSN stats counters */ - struct osi_tsn_stats tsn_stats; - /** MC packets Multiple DMA channel selection flags */ - nveu32_t mc_dmasel; - /** UPHY GBE mode (1 for 10G, 0 for 5G) */ - nveu32_t uphy_gbe_mode; - /** Array of VM IRQ's */ - struct osi_vm_irq_data irq_data[OSI_MAX_VM_IRQS]; - /** number of VM IRQ's */ - nveu32_t num_vm_irqs; - /** PHY interface mode (0/1 for XFI 10/5G, 2/3 for USXGMII 10/5) */ - nveu32_t phy_iface_mode; - /** eqos pad control structure */ - struct core_padctrl padctrl; - /** MGBE MAC instance ID's */ - nveu32_t instance_id; - /** Packet error stats */ - struct osi_core_pkt_err_stats pkt_err_stats; - /** Ethernet controller MAC to MAC Time sync role - * 1 - Primary interface, 2 - secondary interface, 0 - inactive interface - */ - nveu32_t m2m_role; - /** control pps output signal - */ - nveu32_t pps_frq; -#ifdef HSI_SUPPORT - struct osi_hsi_data hsi; -#endif -}; - -/** - * @brief osi_poll_for_mac_reset_complete - Poll Software reset bit in MAC HW - * - * @note - * Algorithm: - * - Invokes EQOS routine to check for SWR (software reset) - * bit in DMA Basic mode register to make sure IP reset was successful. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @pre MAC needs to be out of reset and proper clock configured. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_004 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ - -nve32_t osi_poll_for_mac_reset_complete( - struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_hw_core_init - EQOS MAC, MTL and common DMA initialization. - * - * @note - * Algorithm: - * - Invokes EQOS MAC, MTL and common DMA register init code. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] tx_fifo_size: OSI core private data structure. - * @param[in] rx_fifo_size: OSI core private data structure. - * - * @pre - * - MAC should be out of reset. See osi_poll_for_mac_reset_complete() - * for details. - * - osi_core->base needs to be filled based on ioremap. - * - osi_core->num_mtl_queues needs to be filled. - * - osi_core->mtl_queues[qinx] need to be filled. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_006 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, nveu32_t rx_fifo_size); - -/** - * @brief osi_hw_core_deinit - EQOS MAC deinitialization. - * - * @note - * Algorithm: - * - Stops MAC transmission and reception. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_007 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_start_mac - Start MAC Tx/Rx engine - * - * @note - * Algorithm: - * - Enable MAC Tx and Rx engine. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_008 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_stop_mac - Stop MAC Tx/Rx engine - * - * @note - * Algorithm: - * - Stop MAC Tx and Rx engine - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC DMA deinit should be complete. See osi_hw_dma_deinit() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_009 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_common_isr - Common ISR. - * - * @note - * Algorithm: - * - Takes care of handling the common interrupts accordingly as per - * the MAC IP - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_010 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_set_mode - Set FD/HD mode. - * - * @note - * Algorithm: - * - Takes care of setting HD or FD mode accordingly as per the MAC IP - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mode: Operating mode. (OSI_FULL_DUPLEX/OSI_HALF_DUPLEX) - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_011 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, - const nve32_t mode); - -/** - * @brief osi_set_speed - Set operating speed. - * - * @note - * Algorithm: - * - Takes care of setting the operating speed accordingly as per - * the MAC IP. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] speed: Operating speed. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_012 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, - const nve32_t speed); - -/** - * @brief osi_pad_calibrate - PAD calibration - * - * @note - * Algorithm: - * - Takes care of doing the pad calibration - * accordingly as per the MAC IP. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_013 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 value on failure or pad calibration is disabled - */ -nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_config_fw_err_pkts - Configure forwarding of error packets - * - * @note - * Algorithm: - * - Configure MAC to enable/disable forwarding of error packets. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: Q index. Max OSI_EQOS_MAX_NUM_QUEUES. - * @param[in] fw_err: Enable or disable forwarding of error packets. - * 0: Disable 1: Enable - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_020 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, const nveu32_t fw_err); - -/** - * @brief osi_config_rxcsum_offload - Configure RX checksum offload in MAC. - * - * @note - * Algorithm: - * - Invokes EQOS config RX checksum offload routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Enable/disable flag. 0: Disable 1: Enable - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_017 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t enable); - -/** - * @brief osi_l2_filter - configure L2 mac filter. - * - * @note - * Algorithm: - * - This sequence is used to configure MAC in different packet - * processing modes like promiscuous, multicast, unicast, - * hash unicast/multicast and perfect/inverse matching for L2 DA - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_018 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter); - -/** - * @brief osi_write_phy_reg - Write to a PHY register through MAC over MDIO bus. - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Program data into MAC MDIO data register. - * - Populate required parameters like phy address, phy register etc,, - * in MAC MDIO Address register. write and GMII busy bits needs to be set - * in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be write to PHY. - * @param[in] phydata: Data to write to a PHY register. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_002 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg, - const nveu16_t phydata); - -/** - * @brief osi_read_mmc - invoke function to read actual registers and update - * structure variable mmc - * - * @note - * Algorithm: - * - Read the registers, mask reserve bits if required, update - * structure. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_014 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_read_phy_reg - Read from a PHY register through MAC over MDIO bus. - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Populate required parameters like phy address, phy register etc,, - * in program it in MAC MDIO Address register. Read and GMII busy bits - * needs to be set in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. After this data will be available at MAC MDIO - * data register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be read from PHY. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_003 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval data from PHY register on success - * @retval -1 on failure - */ -nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg); - -/** - * @brief initializing the core operations - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval data from PHY register on success - * @retval -1 on failure - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_001 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - */ -nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_set_systime_to_mac - Handles setting of system time. - * - * @note - * Algorithm: - * - Set current system time to MAC. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] sec: Seconds to be configured. - * @param[in] nsec: Nano seconds to be configured. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_005 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, - const nveu32_t sec, const nveu32_t nsec); - -/** - * @brief osi_adjust_freq - Adjust frequency - * - * @note - * Algorithm: - * - Adjust a drift of +/- comp nanoseconds per second. - * "Compensation" is the difference in frequency between - * the master and slave clocks in Parts Per Billion. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] ppb: Parts per Billion - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_023 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb); - -/** - * @brief osi_adjust_time - Adjust MAC time with system time - * - * @note - * Algorithm: - * - Adjust/update the MAC time (delta time from MAC to system time - * passed in nanoseconds, can be + or -). - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] nsec_delta: Delta time in nano seconds - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->ptp_config.one_nsec_accuracy need to be set to 1 - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_022 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, - nvel64_t nsec_delta); - -/** - * @brief osi_ptp_configuration - Configure PTP - * - * @note - * Algorithm: - * - Configure the PTP registers that are required for PTP. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Enable or disable Time Stamping. 0: Disable 1: Enable - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi->ptp_config.ptp_filter need to be filled accordingly to the - * filter that need to be set for PTP packets. Please check osi_ptp_config - * structure declaration on the bit fields that need to be filled. - * - osi->ptp_config.ptp_clock need to be filled with the ptp system clk. - * Currently it is set to 62500000Hz. - * - osi->ptp_config.ptp_ref_clk_rate need to be filled with the ptp - * reference clock that platform supports. - * - osi->ptp_config.sec need to be filled with current time of seconds - * - osi->ptp_config.nsec need to be filled with current time of nseconds - * - osi->base need to be filled with the ioremapped base address - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_021 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, - const nveu32_t enable); - -/* MAC version specific implementation function prototypes added here - * for misra compliance to have - * 1. Visible prototype for all functions. - * 2. Only one prototype for all function. - */ -void *eqos_get_core_safety_config(void); - -/** - * @brief osi_l3l4_filter - invoke OSI call to add L3/L4 - * filters. - * - * @note - * Algorithm: - * - This routine is to enable/disable L3/l4 filter. - * Check for DCS enable as well as validate channel - * number if dcs_enable is set. After validation, configure L3(IPv4/IPv6) - * filters register for given address. Based on input arguments update - * IPv4/IPv6 source/destination address for L3 layer filtering or source and - * destination Port Number for L4(TCP/UDP) layer - * filtering. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] l_filter: L3L4 filter data structure. - * @param[in] type: L3 filter (ipv4(0) or ipv6(1)) - * or L4 filter (tcp(0) or udp(1)) - * @param[in] dma_routing_enable: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter. - * Max OSI_EQOS_MAX_NUM_CHANS. - * @param[in] is_l4_filter: API call for L3 filter(0) or L4 filter(1) - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - Concurrent invocations to configure filters is not supported. - * OSD driver shall serialize calls. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_019 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - const struct osi_l3_l4_filter l_filter, - const nveu32_t type, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan, - const nveu32_t is_l4_filter); - -/** - * @brief osi_get_mac_version - Reading MAC version - * - * @note - * Algorithm: - * - Reads MAC version and check whether its valid or not. - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] mac_ver: holds mac version. - * - * @pre MAC has to be out of reset. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_015 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, - nveu32_t *mac_ver); - -/** - * @brief osi_get_hw_features - Reading MAC HW features - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] hw_feat: holds the supported features of the hardware. - * - * @pre MAC has to be out of reset. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_016 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat); - -/** - * @brief osi_handle_ioctl - API to handle runtime command - * - * @note - * Algorithm: - * - Handle runtime commands to OSI - * - OSI_CMD_MDC_CONFIG - * Derive MDC clock based on provided AXI_CBB clk - * arg1_u32 - CSR (AXI CBB) clock rate. - * - OSI_CMD_RESTORE_REGISTER - * Restore backup of MAC MMIO address space - * - OSI_CMD_POLL_FOR_MAC_RST - * Poll Software reset bit in MAC HW - * - OSI_CMD_START_MAC - * Start MAC Tx/Rx engine - * - OSI_CMD_STOP_MAC - * Stop MAC Tx/Rx engine - * - OSI_CMD_COMMON_ISR - * Common ISR handler - * - OSI_CMD_PAD_CALIBRATION - * PAD calibration - * - OSI_CMD_READ_MMC - * invoke function to read actual registers and update - * structure variable mmc - * - OSI_CMD_GET_MAC_VER - * Reading MAC version - * arg1_u32 - holds mac version - * - OSI_CMD_VALIDATE_CORE_REG - * Read-validate HW registers for func safety - * - OSI_CMD_RESET_MMC - * invoke function to reset MMC counter and data - * structure - * - OSI_CMD_SAVE_REGISTER - * Take backup of MAC MMIO address space - * - OSI_CMD_MAC_LB - * Configure MAC loopback - * - OSI_CMD_FLOW_CTRL - * Configure flow control settings - * arg1_u32 - Enable or disable flow control settings - * - OSI_CMD_SET_MODE - * Set Full/Half Duplex mode. - * arg1_u32 - mode - * - OSI_CMD_SET_SPEED - * Set Operating speed - * arg1_u32 - Operating speed - * - OSI_CMD_L2_FILTER - * configure L2 mac filter - * l2_filter_struct - OSI filter structure - * - OSI_CMD_RXCSUM_OFFLOAD - * Configure RX checksum offload in MAC - * arg1_u32 - enable(1)/disable(0) - * - OSI_CMD_ADJ_FREQ - * Adjust frequency - * arg6_u32 - Parts per Billion - * - OSI_CMD_ADJ_TIME - * Adjust MAC time with system time - * arg1_u32 - Delta time in nano seconds - * - OSI_CMD_CONFIG_PTP - * Configure PTP - * arg1_u32 - Enable(1) or disable(0) Time Stamping - * - OSI_CMD_GET_AVB - * Get CBS algo and parameters - * avb_struct - osi core avb data structure - * - OSI_CMD_SET_AVB - * Set CBS algo and parameters - * avb_struct - osi core avb data structure - * - OSI_CMD_CONFIG_RX_CRC_CHECK - * Configure CRC Checking for Received Packets - * arg1_u32 - Enable or disable checking of CRC field in - * received pkts - * - OSI_CMD_UPDATE_VLAN_ID - * invoke osi call to update VLAN ID - * arg1_u32 - VLAN ID - * - OSI_CMD_CONFIG_TXSTATUS - * Configure Tx packet status reporting - * Enable(1) or disable(0) tx packet status reporting - * - OSI_CMD_GET_HW_FEAT - * Reading MAC HW features - * hw_feat_struct - holds the supported features of the hardware - * - OSI_CMD_CONFIG_FW_ERR - * Configure forwarding of error packets - * arg1_u32 - queue index, Max OSI_EQOS_MAX_NUM_QUEUES - * arg2_u32 - FWD error enable(1)/disable(0) - * - OSI_CMD_ARP_OFFLOAD - * Configure ARP offload in MAC - * arg1_u32 - Enable/disable flag - * arg7_u8_p - Char array representation of IP address - * - OSI_CMD_VLAN_FILTER - * OSI call for configuring VLAN filter - * vlan_filter - vlan filter structure - * - OSI_CMD_CONFIG_EEE - * Configure EEE LPI in MAC - * arg1_u32 - Enable (1)/disable (0) tx lpi - * arg2_u32 - Tx LPI entry timer in usecs upto - * OSI_MAX_TX_LPI_TIMER (in steps of 8usec) - * - OSI_CMD_L3L4_FILTER - * invoke OSI call to add L3/L4 - * l3l4_filter - l3_l4 filter structure - * arg1_u32 - L3 filter (ipv4(0) or ipv6(1)) - * or L4 filter (tcp(0) or udp(1) - * arg2_u32 - filter based dma routing enable(1) - * arg3_u32 - dma channel for routing based on filter. - * Max OSI_EQOS_MAX_NUM_CHANS. - * arg4_u32 - API call for L3 filter(0) or L4 filter(1) - * - OSI_CMD_SET_SYSTOHW_TIME - * set system to MAC hardware - * arg1_u32 - sec - * arg1_u32 - nsec - * - OSI_CMD_CONFIG_PTP_OFFLOAD - * enable/disable PTP offload feature - * pto_config - ptp offload structure - * - OSI_CMD_PTP_RXQ_ROUTE - * rxq routing to secific queue - * rxq_route - rxq routing information in structure - * - OSI_CMD_CONFIG_FRP - * Issue FRP command to HW - * frp_cmd - FRP command parameter - * - OSI_CMD_CONFIG_RSS - * Configure RSS - * - OSI_CMD_CONFIG_EST - * Configure EST registers and GCL to hw - * est - EST configuration structure - * - OSI_CMD_CONFIG_FPE - * Configuration FPE register and preemptable queue - * fpe - FPE configuration structure - * - * - OSI_CMD_GET_TX_TS - * Command to get TX timestamp for PTP packet - * ts - OSI core timestamp structure - * - * - OSI_CMD_FREE_TS - * Command to free old timestamp for PTP packet - * chan - DMA channel number +1. 0 will be used for onestep - * - * - OSI_CMD_CAP_TSC_PTP - * Capture TSC and PTP time stamp - * ptp_tsc_data - output structure with time - * - * - OSI_CMD_CONF_M2M_TS - * Enable/Disable MAC to MAC time sync for Secondary interface - * enable_disable - 1 - enable, 0- disable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] data: void pointer pointing to osi_ioctl - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data); - -/** - * @brief osi_get_core - Get pointer to osi_core data structure. - * - * @note - * Algorithm: - * - Returns OSI core data structure. - * - * @pre OSD layer should use this as first API to get osi_core pointer and - * use the same in remaning API invocation. - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval valid and unique osi_core pointer on success - * @retval NULL on failure. - */ -struct osi_core_priv_data *osi_get_core(void); - -/** - * @brief osi_hal_handle_ioctl - HW function API to handle runtime command - * - * @note - * Algorithm: - * - Handle runtime commands to OSI - * - OSI_CMD_MDC_CONFIG - * Derive MDC clock based on provided AXI_CBB clk - * arg1_u32 - CSR (AXI CBB) clock rate. - * - OSI_CMD_RESTORE_REGISTER - * Restore backup of MAC MMIO address space - * - OSI_CMD_POLL_FOR_MAC_RST - * Poll Software reset bit in MAC HW - * - OSI_CMD_START_MAC - * Start MAC Tx/Rx engine - * - OSI_CMD_STOP_MAC - * Stop MAC Tx/Rx engine - * - OSI_CMD_COMMON_ISR - * Common ISR handler - * - OSI_CMD_PAD_CALIBRATION - * PAD calibration - * - OSI_CMD_READ_MMC - * invoke function to read actual registers and update - * structure variable mmc - * - OSI_CMD_GET_MAC_VER - * Reading MAC version - * arg1_u32 - holds mac version - * - OSI_CMD_VALIDATE_CORE_REG - * Read-validate HW registers for func safety - * - OSI_CMD_RESET_MMC - * invoke function to reset MMC counter and data - * structure - * - OSI_CMD_SAVE_REGISTER - * Take backup of MAC MMIO address space - * - OSI_CMD_MAC_LB - * Configure MAC loopback - * - OSI_CMD_FLOW_CTRL - * Configure flow control settings - * arg1_u32 - Enable or disable flow control settings - * - OSI_CMD_SET_MODE - * Set Full/Half Duplex mode. - * arg1_u32 - mode - * - OSI_CMD_SET_SPEED - * Set Operating speed - * arg1_u32 - Operating speed - * - OSI_CMD_L2_FILTER - * configure L2 mac filter - * l2_filter_struct - OSI filter structure - * - OSI_CMD_RXCSUM_OFFLOAD - * Configure RX checksum offload in MAC - * arg1_u32 - enable(1)/disable(0) - * - OSI_CMD_ADJ_FREQ - * Adjust frequency - * arg6_u32 - Parts per Billion - * - OSI_CMD_ADJ_TIME - * Adjust MAC time with system time - * arg1_u32 - Delta time in nano seconds - * - OSI_CMD_CONFIG_PTP - * Configure PTP - * arg1_u32 - Enable(1) or disable(0) Time Stamping - * - OSI_CMD_GET_AVB - * Get CBS algo and parameters - * avb_struct - osi core avb data structure - * - OSI_CMD_SET_AVB - * Set CBS algo and parameters - * avb_struct - osi core avb data structure - * - OSI_CMD_CONFIG_RX_CRC_CHECK - * Configure CRC Checking for Received Packets - * arg1_u32 - Enable or disable checking of CRC field in - * received pkts - * - OSI_CMD_UPDATE_VLAN_ID - * invoke osi call to update VLAN ID - * arg1_u32 - VLAN ID - * - OSI_CMD_CONFIG_TXSTATUS - * Configure Tx packet status reporting - * Enable(1) or disable(0) tx packet status reporting - * - OSI_CMD_GET_HW_FEAT - * Reading MAC HW features - * hw_feat_struct - holds the supported features of the hardware - * - OSI_CMD_CONFIG_FW_ERR - * Configure forwarding of error packets - * arg1_u32 - queue index, Max OSI_EQOS_MAX_NUM_QUEUES - * arg2_u32 - FWD error enable(1)/disable(0) - * - OSI_CMD_ARP_OFFLOAD - * Configure ARP offload in MAC - * arg1_u32 - Enable/disable flag - * arg7_u8_p - Char array representation of IP address - * - OSI_CMD_VLAN_FILTER - * OSI call for configuring VLAN filter - * vlan_filter - vlan filter structure - * - OSI_CMD_CONFIG_EEE - * Configure EEE LPI in MAC - * arg1_u32 - Enable (1)/disable (0) tx lpi - * arg2_u32 - Tx LPI entry timer in usecs upto - * OSI_MAX_TX_LPI_TIMER (in steps of 8usec) - * - OSI_CMD_L3L4_FILTER - * invoke OSI call to add L3/L4 - * l3l4_filter - l3_l4 filter structure - * arg1_u32 - L3 filter (ipv4(0) or ipv6(1)) - * or L4 filter (tcp(0) or udp(1) - * arg2_u32 - filter based dma routing enable(1) - * arg3_u32 - dma channel for routing based on filter. - * Max OSI_EQOS_MAX_NUM_CHANS. - * arg4_u32 - API call for L3 filter(0) or L4 filter(1) - * - OSI_CMD_SET_SYSTOHW_TIME - * set system to MAC hardware - * arg1_u32 - sec - * arg1_u32 - nsec - * - OSI_CMD_CONFIG_PTP_OFFLOAD - * enable/disable PTP offload feature - * pto_config - ptp offload structure - * - OSI_CMD_PTP_RXQ_ROUTE - * rxq routing to secific queue - * rxq_route - rxq routing information in structure - * - OSI_CMD_CONFIG_FRP - * Issue FRP command to HW - * frp_cmd - FRP command parameter - * - OSI_CMD_CONFIG_RSS - * Configure RSS - * - OSI_CMD_CONFIG_EST - * Configure EST registers and GCL to hw - * est - EST configuration structure - * - OSI_CMD_CONFIG_FPE - * Configuration FPE register and preemptable queue - * fpe - FPE configuration structure - * - * - OSI_CMD_GET_TX_TS - * Command to get TX timestamp for PTP packet - * ts - OSI core timestamp structure - * - * - OSI_CMD_FREE_TS - * Command to free old timestamp for PTP packet - * chan - DMA channel number +1. 0 will be used for onestep - * - * - OSI_CMD_CAP_TSC_PTP - * Capture TSC and PTP time stamp - * ptp_tsc_data - output structure with time - * - * - OSI_CMD_CONF_M2M_TS - * Enable/Disable MAC to MAC time sync for Secondary interface - * enable_disable - 1 - enable, 0- disable - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] data: void pointer pointing to osi_ioctl - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data); -/** - * @brief osi_hal_hw_core_init - HW API for EQOS MAC, MTL and common DMA - * initialization. - * - * @note - * Algorithm: - * - Invokes EQOS MAC, MTL and common DMA register init code. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] tx_fifo_size: OSI core private data structure. - * @param[in] rx_fifo_size: OSI core private data structure. - * - * @pre - * - MAC should be out of reset. See osi_poll_for_mac_reset_complete() - * for details. - * - osi_core->base needs to be filled based on ioremap. - * - osi_core->num_mtl_queues needs to be filled. - * - osi_core->mtl_queues[qinx] need to be filled. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETRM_006 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, nveu32_t rx_fifo_size); - -/** - * @brief osi_hal_hw_core_deinit - HW API for MAC deinitialization. - * - * @note - * Algorithm: - * - Stops MAC transmission and reception. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * Traceability Details: - * - SWUD_ID: TODO - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_hal_write_phy_reg - HW API to Write to a PHY register through MAC - * over MDIO bus. - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Program data into MAC MDIO data register. - * - Populate required parameters like phy address, phy register etc,, - * in MAC MDIO Address register. write and GMII busy bits needs to be set - * in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be write to PHY. - * @param[in] phydata: Data to write to a PHY register. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: TODO - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg, - const nveu16_t phydata); - -/** - * @brief osi_hal_read_phy_reg - HW API to Read from a PHY register through MAC - * over MDIO bus. - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Populate required parameters like phy address, phy register etc,, - * in program it in MAC MDIO Address register. Read and GMII busy bits - * needs to be set in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. After this data will be available at MAC MDIO - * data register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be read from PHY. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: TODO - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval data from PHY register on success - * @retval -1 on failure - */ -nve32_t osi_hal_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg); -#endif /* INCLUDED_OSI_CORE_H */ - diff --git a/include/osi_dma.h b/include/osi_dma.h deleted file mode 100644 index 934784f..0000000 --- a/include/osi_dma.h +++ /dev/null @@ -1,1550 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 INCLUDED_OSI_DMA_H -#define INCLUDED_OSI_DMA_H - -#include -#include "osi_dma_txrx.h" - -/* - * @addtogroup Helper Helper MACROS - * - * @brief These flags are used for PTP time synchronization - * @{ - */ -#define OSI_PTP_SYNC_MASTER OSI_BIT(0) -#define OSI_PTP_SYNC_SLAVE OSI_BIT(1) -#define OSI_PTP_SYNC_ONESTEP OSI_BIT(2) -#define OSI_PTP_SYNC_TWOSTEP OSI_BIT(3) -#define OSI_DELAY_1US 1U -/** @} */ - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#define OSI_NET_IP_ALIGN 0x2U -#define NV_VLAN_HLEN 0x4U -#define OSI_ETH_HLEN 0xEU - -#define OSI_INVALID_VALUE 0xFFFFFFFFU - -#define OSI_ONE_MEGA_HZ 1000000U -#define OSI_ULLONG_MAX (~0ULL) - -/* Compiler hints for branch prediction */ -#define osi_likely(x) __builtin_expect(!!(x), 1) -/** @} */ - -/** - * @addtogroup Channel Mask - * @brief Chanel mask for Tx and Rx interrupts - * @{ - */ -#define OSI_VM_IRQ_TX_CHAN_MASK(x) OSI_BIT((x) * 2U) -#define OSI_VM_IRQ_RX_CHAN_MASK(x) OSI_BIT(((x) * 2U) + 1U) -/** @} */ - -/** - * OSI error macro definition, - * @param[in] priv: OSD private data OR NULL - * @param[in] type: error type - * @param[in] err: error string - * @param[in] loga: error additional information - */ -#define OSI_DMA_ERR(priv, type, err, loga) \ -{ \ - osi_dma->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_ERR, type, err, loga); \ -} - -#ifndef OSI_STRIPPED_LIB -/** - * OSI info macro definition - * @param[in] priv: OSD private data OR NULL - * @param[in] type: error type - * @param[in] err: error string - * @param[in] loga: error additional information - */ -#define OSI_DMA_INFO(priv, type, err, loga) \ -{ \ - osi_dma->osd_ops.ops_log(priv, __func__, __LINE__, \ - OSI_LOG_INFO, type, err, loga);\ -} -#endif /* !OSI_STRIPPED_LIB */ -/** - * @addtogroup EQOS-PKT Packet context fields - * - * @brief These flags are used to convey context information about a packet - * between OSI and OSD. The context information includes - * whether a VLAN tag is to be inserted for a packet, - * whether a received packet is valid, - * whether checksum offload is to be enabled for the packet upon transmit, - * whether IP checksum offload is to be enabled for the packet upon transmit, - * whether TCP segmentation offload is to be enabled for the packet, - * whether the HW should timestamp transmit/arrival of a packet respectively - * whether a paged buffer. - * @{ - */ -/** VLAN packet */ -#define OSI_PKT_CX_VLAN OSI_BIT(0) -/** CSUM packet */ -#define OSI_PKT_CX_CSUM OSI_BIT(1) -/** TSO packet */ -#define OSI_PKT_CX_TSO OSI_BIT(2) -/** PTP packet */ -#define OSI_PKT_CX_PTP OSI_BIT(3) -/** Paged buffer */ -#define OSI_PKT_CX_PAGED_BUF OSI_BIT(4) -/** Rx packet has RSS hash */ -#define OSI_PKT_CX_RSS OSI_BIT(5) -/** Valid packet */ -#define OSI_PKT_CX_VALID OSI_BIT(10) -/** Update Packet Length in Tx Desc3 */ -#define OSI_PKT_CX_LEN OSI_BIT(11) -/** IP CSUM packet */ -#define OSI_PKT_CX_IP_CSUM OSI_BIT(12) -/** @} */ - -/** - * @addtogroup SLOT function context fields - * - * @brief These flags are used for DMA channel Slot context configuration - * @{ - */ -#ifndef OSI_STRIPPED_LIB -#define OSI_SLOT_INTVL_DEFAULT 125U -#define OSI_SLOT_INTVL_MAX 4095U -#endif /* !OSI_STRIPPED_LIB */ -#define OSI_SLOT_NUM_MAX 16U -/** @} */ - -/** - * @addtogroup EQOS-TX Tx done packet context fields - * - * @brief These flags used to convey transmit done packet context information, - * whether transmitted packet used a paged buffer, whether transmitted packet - * has an tx error, whether transmitted packet has an TS - * - * @{ - */ -/** Flag to indicate if buffer programmed in desc. is DMA map'd from - * linear/Paged buffer from OS layer */ -#define OSI_TXDONE_CX_PAGED_BUF OSI_BIT(0) -/** Flag to indicate if there was any tx error */ -#define OSI_TXDONE_CX_ERROR OSI_BIT(1) -/** Flag to indicate the availability of time stamp */ -#define OSI_TXDONE_CX_TS OSI_BIT(2) -/** Flag to indicate the delayed availability of time stamp */ -#define OSI_TXDONE_CX_TS_DELAYED OSI_BIT(3) -/** @} */ - -/** - * @addtogroup EQOS-CHK Checksum offload results - * - * @brief Flag to indicate the result from checksum offload engine - * to SW network stack in receive path. - * OSI_CHECKSUM_NONE indicates that HW checksum offload - * engine did not verify the checksum, SW network stack has to do it. - * OSI_CHECKSUM_UNNECESSARY indicates that HW validated the - * checksum already, network stack can skip validation. - * @{ - */ -/* Checksum offload result flags */ -#ifndef OSI_STRIPPED_LIB -#define OSI_CHECKSUM_NONE 0x0U -#endif /* OSI_STRIPPED_LIB */ -/* TCP header/payload */ -#define OSI_CHECKSUM_TCPv4 OSI_BIT(0) -/* UDP header/payload */ -#define OSI_CHECKSUM_UDPv4 OSI_BIT(1) -/* TCP/UDP checksum bad */ -#define OSI_CHECKSUM_TCP_UDP_BAD OSI_BIT(2) -/* IPv6 TCP header/payload */ -#define OSI_CHECKSUM_TCPv6 OSI_BIT(4) -/* IPv6 UDP header/payload */ -#define OSI_CHECKSUM_UDPv6 OSI_BIT(5) -/* IPv4 header */ -#define OSI_CHECKSUM_IPv4 OSI_BIT(6) -/* IPv4 header checksum bad */ -#define OSI_CHECKSUM_IPv4_BAD OSI_BIT(7) -/* Checksum check not required */ -#define OSI_CHECKSUM_UNNECESSARY OSI_BIT(8) -/** @} */ - -/** - * @addtogroup EQOS-RX Rx SW context flags - * - * @brief Flags to share info about the Rx SW context structure per descriptor - * between OSI and OSD. - * @{ - */ -/* Rx swcx flags */ -#define OSI_RX_SWCX_REUSE OSI_BIT(0) -#define OSI_RX_SWCX_BUF_VALID OSI_BIT(1) -/** Packet is processed by driver */ -#define OSI_RX_SWCX_PROCESSED OSI_BIT(3) - -/** @} */ - - -/** - * @addtogroup RSS-HASH type - * - * @brief Macros to represent to type of packet for hash stored in receive packet - * context. - * @{ - */ -#define OSI_RX_PKT_HASH_TYPE_L2 0x1U -#define OSI_RX_PKT_HASH_TYPE_L3 0x2U -#define OSI_RX_PKT_HASH_TYPE_L4 0x3U -/** @} */ - -/** - * @addtogroup OSI-INTR OSI DMA interrupt handling macros. - * - * @brief Macros to pass osi_handle_dma_intr() API to handle - * the interrupts between OSI and OSD. - * @{ - */ -#define OSI_DMA_CH_TX_INTR 0U -#define OSI_DMA_CH_RX_INTR 1U -#define OSI_DMA_INTR_DISABLE 0U -#define OSI_DMA_INTR_ENABLE 1U -/** @} */ - -/** - * @addtogroup OSI_DMA-DEBUG helper macros - * - * @brief Helper macros for OSI dma debugging. - * @{ - */ -#ifdef OSI_DEBUG -#define OSI_DMA_IOCTL_CMD_REG_DUMP 1U -#define OSI_DMA_IOCTL_CMD_STRUCTS_DUMP 2U -#endif /* OSI_DEBUG */ -/** @} */ - -/** - * @brief Maximum buffer length per DMA descriptor (16KB - 1). - */ -#define OSI_TX_MAX_BUFF_SIZE 0x3FFFU - -/** - * @brief OSI packet error stats - */ -struct osi_pkt_err_stats { - /** IP Header Error */ - nveu64_t ip_header_error; - /** Jabber time out Error */ - nveu64_t jabber_timeout_error; - /** Packet Flush Error */ - nveu64_t pkt_flush_error; - /** Payload Checksum Error */ - nveu64_t payload_cs_error; - /** Loss of Carrier Error */ - nveu64_t loss_of_carrier_error; - /** No Carrier Error */ - nveu64_t no_carrier_error; - /** Late Collision Error */ - nveu64_t late_collision_error; - /** Excessive Collision Error */ - nveu64_t excessive_collision_error; - /** Excessive Deferal Error */ - nveu64_t excessive_deferal_error; - /** Under Flow Error */ - nveu64_t underflow_error; - /** Rx CRC Error */ - nveu64_t rx_crc_error; - /** Rx Frame Error */ - nveu64_t rx_frame_error; - /** clear_tx_pkt_err_stats() API invoked */ - nveu64_t clear_tx_err; - /** clear_rx_pkt_err_stats() API invoked */ - nveu64_t clear_rx_err; - /** FRP Parsed count, includes accept - * routing-bypass, or result-bypass count. - */ - unsigned long frp_parsed; - /** FRP Dropped count */ - unsigned long frp_dropped; - /** FRP Parsing Error count */ - unsigned long frp_err; - /** FRP Incomplete Parsing */ - unsigned long frp_incomplete; -}; - -/** - * @brief Receive Descriptor - */ -struct osi_rx_desc { - /** Receive Descriptor 0 */ - nveu32_t rdes0; - /** Receive Descriptor 1 */ - nveu32_t rdes1; - /** Receive Descriptor 2 */ - nveu32_t rdes2; - /** Receive Descriptor 3 */ - nveu32_t rdes3; -}; - -/** - * @brief Receive descriptor software context - */ -struct osi_rx_swcx { - /** DMA buffer physical address */ - nveu64_t buf_phy_addr; - /** DMA buffer virtual address */ - void *buf_virt_addr; - /** Length of buffer */ - nveu32_t len; - /** Flags to share info about Rx swcx between OSD and OSI */ - nveu32_t flags; -}; - -/** - * @brief - Received packet context. This is a single instance - * and it is reused for all rx packets. - */ -struct osi_rx_pkt_cx { - /** Bit map which holds the features that rx packets supports */ - nveu32_t flags; - /** Stores the Rx csum */ - nveu32_t rxcsum; - /** Stores the VLAN tag ID in received packet */ - nveu32_t vlan_tag; - /** Length of received packet */ - nveu32_t pkt_len; - /** Stores received packet hash */ - nveu32_t rx_hash; - /** Store type of packet for which hash carries at rx_hash */ - nveu32_t rx_hash_type; - /** TS in nsec for the received packet */ - nveul64_t ns; -}; - -/** - * @brief DMA channel Rx ring. The number of instances depends on the - * number of DMA channels configured - */ -struct osi_rx_ring { - /** Pointer to Rx DMA descriptor */ - struct osi_rx_desc *rx_desc; - /** Pointer to Rx DMA descriptor software context information */ - struct osi_rx_swcx *rx_swcx; - /** Physical address of Rx DMA descriptor */ - nveu64_t rx_desc_phy_addr; - /** Descriptor index current reception */ - nveu32_t cur_rx_idx; - /** Descriptor index for descriptor re-allocation */ - nveu32_t refill_idx; - /** Receive packet context */ - struct osi_rx_pkt_cx rx_pkt_cx; -}; - -/** - *@brief Transmit descriptor software context - */ -struct osi_tx_swcx { - /** Physical address of DMA mapped buffer */ - nveu64_t buf_phy_addr; - /** Virtual address of DMA buffer */ - void *buf_virt_addr; - /** Length of buffer */ - nveu32_t len; - /** Flag to keep track of whether buffer pointed by buf_phy_addr - * is a paged buffer/linear buffer */ - nveu32_t is_paged_buf; - /** Flag to keep track of SWCX - * Bit 0 is_paged_buf - whether buffer pointed by buf_phy_addr - * is a paged buffer/linear buffer - * Bit 1 PTP hwtime form timestamp registers */ - unsigned int flags; - /** Packet id of packet for which TX timestamp needed */ - unsigned int pktid; - /** dma channel number for osd use */ - nveu32_t chan; - /** reserved field 1 for future use */ - nveu64_t rsvd1; - /** reserved field 2 for future use */ - nveu64_t rsvd2; -}; - -/** - * @brief Transmit descriptor - */ -struct osi_tx_desc { - /** Transmit descriptor 0 */ - nveu32_t tdes0; - /** Transmit descriptor 1 */ - nveu32_t tdes1; - /** Transmit descriptor 2 */ - nveu32_t tdes2; - /** Transmit descriptor 3 */ - nveu32_t tdes3; -}; - -/** - * @brief Transmit packet context for a packet. This is a single instance - * and it is reused for all tx packets. - */ -struct osi_tx_pkt_cx { - /** Holds the features which a Tx packets supports */ - nveu32_t flags; - /** Stores the VLAN tag ID */ - nveu32_t vtag_id; - /** Descriptor count */ - nveu32_t desc_cnt; - /** Max. segment size for TSO/USO/GSO/LSO packet */ - nveu32_t mss; - /** Length of application payload */ - nveu32_t payload_len; - /** Length of transport layer tcp/udp header */ - nveu32_t tcp_udp_hdrlen; - /** Length of all headers (ethernet/ip/tcp/udp) */ - nveu32_t total_hdrlen; -}; - -/** - * @brief Transmit done packet context for a packet - */ -struct osi_txdone_pkt_cx { - /** Indicates status flags for Tx complete (tx error occurred, or - * indicate whether desc had buf mapped from paged/linear memory etc) */ - nveu32_t flags; - /** TS captured for the tx packet and this is valid only when the PTP - * bit is set in fields */ - nveul64_t ns; - /** Passing packet id to map TX time to packet */ - unsigned int pktid; -}; - -/** - * @brief DMA channel Tx ring. The number of instances depends on the - * number of DMA channels configured - */ -struct osi_tx_ring { - /** Pointer to tx dma descriptor */ - struct osi_tx_desc *tx_desc; - /** Pointer to tx dma descriptor software context information */ - struct osi_tx_swcx *tx_swcx; - /** Physical address of Tx descriptor */ - nveu64_t tx_desc_phy_addr; - /** Descriptor index current transmission */ - nveu32_t cur_tx_idx; - /** Descriptor index for descriptor cleanup */ - nveu32_t clean_idx; - /** Slot function check */ - nveu32_t slot_check; - /** Slot number */ - nveu32_t slot_number; - /** Transmit packet context */ - struct osi_tx_pkt_cx tx_pkt_cx; - /** Transmit complete packet context information */ - struct osi_txdone_pkt_cx txdone_pkt_cx; - /** Number of packets or frames transmitted */ - nveu32_t frame_cnt; -}; - -/** - * @brief osi_xtra_dma_stat_counters - OSI DMA extra stats counters - */ -struct osi_xtra_dma_stat_counters { - /** Per Q TX packet count */ - nveu64_t q_tx_pkt_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Per Q RX packet count */ - nveu64_t q_rx_pkt_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Per Q TX complete call count */ - nveu64_t tx_clean_n[OSI_MGBE_MAX_NUM_QUEUES]; - /** Total number of tx packets count */ - nveu64_t tx_pkt_n; - /** Total number of rx packet count */ - nveu64_t rx_pkt_n; - /** Total number of VLAN RX packet count */ - nveu64_t rx_vlan_pkt_n; - /** Total number of VLAN TX packet count */ - nveu64_t tx_vlan_pkt_n; - /** Total number of TSO packet count */ - nveu64_t tx_tso_pkt_n; -}; - -struct osi_dma_priv_data; - -/** - *@brief OSD DMA callbacks - */ -struct osd_dma_ops { - /** DMA transmit complete callback */ - void (*transmit_complete)(void *priv, const struct osi_tx_swcx *swcx, - const struct osi_txdone_pkt_cx - *txdone_pkt_cx); - /** DMA receive packet callback */ - void (*receive_packet)(void *priv, struct osi_rx_ring *rx_ring, - nveu32_t chan, nveu32_t dma_buf_len, - const struct osi_rx_pkt_cx *rx_pkt_cx, - struct osi_rx_swcx *rx_swcx); - /** RX buffer reallocation callback */ - void (*realloc_buf)(void *priv, struct osi_rx_ring *rx_ring, - nveu32_t chan); - /**.ops_log function callback */ - void (*ops_log)(void *priv, const nve8_t *func, nveu32_t line, - nveu32_t level, nveu32_t type, const nve8_t *err, - nveul64_t loga); - /**.ops_log function callback */ - void (*udelay)(nveu64_t usec); -#ifdef OSI_DEBUG - /**.printf function callback */ - void (*printf)(struct osi_dma_priv_data *osi_dma, - nveu32_t type, - const char *fmt, ...); -#endif /* OSI_DEBUG */ -}; - -/** - * @brief The OSI DMA IOCTL data structure. - */ -struct osi_dma_ioctl_data { - /** IOCTL command number */ - nveu32_t cmd; -}; - -/** - * @brief The OSI DMA private data structure. - */ -struct osi_dma_priv_data { - /** Array of pointers to DMA Tx channel Ring */ - struct osi_tx_ring *tx_ring[OSI_MGBE_MAX_NUM_CHANS]; - /** Array of pointers to DMA Rx channel Ring */ - struct osi_rx_ring *rx_ring[OSI_MGBE_MAX_NUM_CHANS]; - /** Memory mapped base address of MAC IP */ - void *base; - /** Pointer to OSD private data structure */ - void *osd; - /** MAC HW type (EQOS) */ - nveu32_t mac; - /** Number of channels enabled in MAC */ - nveu32_t num_dma_chans; - /** Array of supported DMA channels */ - nveu32_t dma_chans[OSI_MGBE_MAX_NUM_CHANS]; - /** DMA Rx channel buffer length at HW level */ - nveu32_t rx_buf_len; - /** MTU size */ - nveu32_t mtu; - /** Packet error stats */ - struct osi_pkt_err_stats pkt_err_stats; - /** Extra DMA stats */ - struct osi_xtra_dma_stat_counters dstats; - /** Receive Interrupt Watchdog Timer Count Units */ - nveu32_t rx_riwt; - /** Flag which decides riwt is enabled(1) or disabled(0) */ - nveu32_t use_riwt; - /** Max no of pkts to be received before triggering Rx interrupt */ - nveu32_t rx_frames; - /** Flag which decides rx_frames is enabled(1) or disabled(0) */ - nveu32_t use_rx_frames; - /** Transmit Interrupt Software Timer Count Units */ - nveu32_t tx_usecs; - /** Flag which decides Tx timer is enabled(1) or disabled(0) */ - nveu32_t use_tx_usecs; - /** Max no of pkts to transfer before triggering Tx interrupt */ - nveu32_t tx_frames; - /** Flag which decides tx_frames is enabled(1) or disabled(0) */ - nveu32_t use_tx_frames; - /** Flag which decides virtualization is enabled(1) or disabled(0) */ - nveu32_t use_virtualization; - /** Functional safety config to do periodic read-verify of - * certain safety critical dma registers */ - void *safety_config; - /** Array of DMA channel slot snterval value from DT */ - nveu32_t slot_interval[OSI_MGBE_MAX_NUM_CHANS]; - /** Array of DMA channel slot enabled status from DT*/ - nveu32_t slot_enabled[OSI_MGBE_MAX_NUM_CHANS]; - /** DMA callback ops structure */ - struct osd_dma_ops osd_ops; - /** Virtual address of reserved DMA buffer */ - void *resv_buf_virt_addr; - /** Physical address of reserved DMA buffer */ - nveu64_t resv_buf_phy_addr; - /** Tegra Pre-si platform info */ - nveu32_t pre_si; - /** PTP flags - * OSI_PTP_SYNC_MASTER - acting as master - * OSI_PTP_SYNC_SLAVE - acting as slave - * OSI_PTP_SYNC_ONESTEP - one-step mode - * OSI_PTP_SYNC_TWOSTEP - two step mode - */ - unsigned int ptp_flag; - /** OSI DMA IOCTL data */ - struct osi_dma_ioctl_data ioctl_data; -#ifdef OSI_DEBUG - /** Flag to enable/disable descriptor dump */ - nveu32_t enable_desc_dump; -#endif /* OSI_DEBUG */ - /** Flag which checks is ethernet server enabled(1) or disabled(0) */ - nveu32_t is_ethernet_server; - /** DMA Tx channel ring size */ - nveu32_t tx_ring_sz; - /** DMA Rx channel ring size */ - nveu32_t rx_ring_sz; -}; - -/** - * @brief osi_disable_chan_tx_intr - Disables DMA Tx channel interrupts. - * - * @note - * Algorithm: - * - Disables Tx interrupts at wrapper level. - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_001 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief osi_enable_chan_tx_intr - Enable DMA Tx channel interrupts. - * - * @note - * Algorithm: - * - Enables Tx interrupts at wrapper level. - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_002 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief osi_disable_chan_rx_intr - Disable DMA Rx channel interrupts. - * - * @note - * Algorithm: - * - Disables Rx interrupts at wrapper level. - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_003 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief osi_enable_chan_rx_intr - Enable DMA Rx channel interrupts. - * - * @note - * Algorithm: - * - Enables Rx interrupts at wrapper level. - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_004 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief osi_get_global_dma_status - Gets DMA status. - * - * Algorithm: Returns global DMA Tx/Rx interrupt status - * - * @param[in] osi_dma: DMA private data. - * - * @note - * Dependencies: None. - * Protection: None. - * - * @retval status - */ -nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_clear_vm_tx_intr - Handles VM Tx interrupt source. - * - * Algorithm: Clear Tx interrupt source at wrapper level and DMA level. - * - * @param[in] osi_dma: DMA private data. - * @param[in] chan: DMA tx channel number. - * - * @note - * 1) MAC needs to be out of reset and proper clocks need to be configured. - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief osi_clear_vm_rx_intr - Handles VM Rx interrupt source. - * - * Algorithm: Clear Rx interrupt source at wrapper level and DMA level. - * - * @param[in] osi_dma: DMA private data. - * @param[in] chan: DMA rx channel number. - * - * @note - * 1) MAC needs to be out of reset and proper clocks need to be configured. - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan); - -/** - * @brief Start DMA - * - * @note - * Algorithm: - * - Start the DMA for specific MAC - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx/Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_005 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); - -/** - * @brief osi_stop_dma - Stop DMA - * - * @note - * Algorithm: - * - Stop the DMA for specific MAC - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx/Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_006 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan); - -/** - * @brief osi_get_refill_rx_desc_cnt - Rx descriptors count that needs to refill - * - * @note - * Algorithm: - * - subtract current index with fill (need to cleanup) - * to get Rx descriptors count that needs to refill. - * - * @param[in] rx_ring: DMA channel Rx ring. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_007 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval "Number of available free descriptors." - */ -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, - unsigned int chan); - -/** - * @brief osi_rx_dma_desc_init - DMA Rx descriptor init - * - * @note - * Algorithm: - * - Initialize a Rx DMA descriptor. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in, out] rx_ring: HW ring corresponding to Rx DMA channel. - * @param[in] chan: Rx DMA channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - rx_swcx->buf_phy_addr need to be filled with DMA mapped address - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_008 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, nveu32_t chan); - -/** - * @brief Updates rx buffer length. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - osi_dma->mtu need to be filled with current MTU size <= 9K - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_009 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_hw_transmit - Initialize Tx DMA descriptors for a channel - * - * @note - * Algorithm: - * - Initialize Transmit descriptors with DMA mappable buffers, - * set OWN bit, Tx ring length and set starting address of Tx DMA channel - * Tx ring base address in Tx DMA registers. - * - * @param[in, out] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - DMA channel need to be started, see osi_start_dma - * - Need to set update tx_pkt_cx->flags accordingly as per the - * requirements - * OSI_PKT_CX_VLAN OSI_BIT(0) - * OSI_PKT_CX_CSUM OSI_BIT(1) - * OSI_PKT_CX_TSO OSI_BIT(2) - * OSI_PKT_CX_PTP OSI_BIT(3) - * - tx_pkt_cx->desc_cnt need to be populated which holds the number - * of swcx descriptors allocated for that packet - * - tx_swcx structure need to be filled for per packet with the - * buffer len, DMA mapped address of buffer for each descriptor - * consumed by the packet - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_010 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan); - -/** - * @brief osi_process_tx_completions - Process Tx complete on DMA channel ring. - * - * @note - * Algorithm: - * - This function will be invoked by OSD layer to process Tx - * complete interrupt. - * - First checks whether descriptor owned by DMA or not. - * - Invokes OSD layer to release DMA address and Tx buffer which are - * updated as part of transmit routine. - * - * @param[in, out] osi_dma: OSI dma private data structure. - * @param[in] chan: Channel number on which Tx complete need to be done. - * Max OSI_EQOS_MAX_NUM_CHANS. - * @param[in] budget: Threshold for reading the packets at a time. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - DMA need to be started, see osi_start_dma - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_011 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @returns Number of descriptors (buffers) processed on success else -1. - */ -nve32_t osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, nve32_t budget); - -/** - * @brief osi_process_rx_completions - Read data from rx channel descriptors - * - * @note - * Algorithm: - * - This routine will be invoked by OSD layer to get the - * data from Rx descriptors and deliver the packet to the stack. - * - Checks descriptor owned by DMA or not. - * - If rx buffer is reserve buffer, reallocate receive buffer and - * read next descriptor. - * - Get the length from Rx descriptor - * - Invokes OSD layer to deliver the packet to network stack. - * - Re-allocate the receive buffers, populate Rx descriptor and - * handover to DMA. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * @param[in] chan: Rx DMA channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * @param[in] budget: Threshold for reading the packets at a time. - * @param[out] more_data_avail: Pointer to more data available flag. OSI fills - * this flag if more rx packets available to read(1) or not(0). - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - DMA need to be started, see osi_start_dma - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_012 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @returns Number of descriptors (buffers) processed on success else -1. - */ -nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, nve32_t budget, - nveu32_t *more_data_avail); - -/** - * @brief osi_hw_dma_init - Initialize DMA - * - * @note - * Algorithm: - * - Takes care of initializing the tx, rx ring and descriptors - * based on the number of channels selected. - * - * @param[in, out] osi_dma: OSI DMA private data. - * - * @pre - * - Allocate memory for osi_dma - * - MAC needs to be out of reset and proper clocks need to be configured. - * - Number of dma channels osi_dma->num_dma_chans - * - channel list osi_dma->dma_chan - * - base address osi_dma->base - * - allocate tx ring osi_dma->tx_ring[chan] for each channel - * based on TX_DESC_CNT (256) - * - allocate tx descriptors osi_dma->tx_ring[chan]->tx_desc for all - * channels and dma map it. - * - allocate tx sw descriptors osi_dma->tx_ring[chan]->tx_swcx for all - * channels - * - allocate rx ring osi_dma->rx_ring[chan] for each channel - * based on RX_DESC_CNT (256) - * - allocate rx descriptors osi_dma->rx_ring[chan]->rx_desc for all - * channels and dma map it. - * - allocate rx sw descriptors osi_dma->rx_ring[chan]->rx_swcx for all - * channels - * - osi_dma->use_riwt ==> OSI_DISABLE/OSI_ENABLE - * - osi_dma->rx_riwt ===> Actual value read from DT - * - osi_dma->use_rx_frames ==> OSI_DISABLE/OSI_ENABLE - * - osi_dma->rx_frames ===> Actual value read from DT - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_013 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_hw_dma_deinit - De initialize DMA - * - * @note - * Algorithm: - * - Takes care of stopping the MAC - * - * @param[in] osi_dma: OSI DMA private data. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_014 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_init_dma_ops - Initialize DMA operations - * - * @param[in, out] osi_dma: OSI DMA private data. - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_015 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_dma_get_systime_from_mac - Get system time - * - * @note - * Algorithm: - * - Gets the current system time - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[out] sec: Value read in Seconds - * @param[out] nsec: Value read in Nano seconds - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_016 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, - nveu32_t *sec, nveu32_t *nsec); - -/** - * @brief osi_is_mac_enabled - Checks if MAC is enabled. - * - * @note - * Algorithm: - * - Reads MAC MCR register for Tx and Rx enabled bits. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - SWUD_ID: ETHERNET_NVETHERNETCL_017 - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval OSI_ENABLE if MAC enabled. - * @retval OSI_DISABLE otherwise. - */ -nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma); - -/** - * @brief osi_handle_dma_intr - Handles DMA interrupts. - * - * @note - * Algorithm: - * - Enables/Disables DMA CH TX/RX/VM inetrrupts. - * - * @param[in] osi_dma: OSI DMA private data. - * @param[in] chan: DMA Rx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * @param[in] tx_rx: Indicates whether DMA channel is Tx or Rx. - * OSI_DMA_CH_TX_INTR for Tx interrupt. - * OSI_DMA_CH_RX_INTR for Rx interrupt. - * @param[in] en_dis: Enable/Disable DMA channel interrupts. - * OSI_DMA_INTR_DISABLE for disabling the interrupt. - * OSI_DMA_INTR_ENABLE for enabling the interrupt. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OS Dependent layer and pass corresponding channel number. - * - * @note - * Traceability Details: TBD - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: Yes - * - Signal handler: Yes - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, nveu32_t tx_rx, nveu32_t en_dis); - -/** - * @brief osi_dma_ioctl - OSI DMA IOCTL - * - * @param[in] osi_dma: OSI DMA private data. - * - * @note - * Traceability Details: TBD - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma); -#ifndef OSI_STRIPPED_LIB -/** - * @brief - Read-validate HW registers for func safety. - * - * @note - * Algorithm: - * - Reads pre-configured list of DMA configuration registers - * and compares with last written value for any modifications. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC has to be out of reset. - * - osi_hw_dma_init has to be called. Internally this would initialize - * the safety_config (see osi_dma_priv_data) based on MAC version and - * which specific registers needs to be validated periodically. - * - Invoke this call if (osi_dma_priv_data->safety_config != OSI_NULL) - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_clear_tx_pkt_err_stats - Clear tx packet error stats. - * - * @note - * Algorithm: - * - This function will be invoked by OSD layer to clear the - * tx stats mentioned in osi_dma->pkt_err_stats structure - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_config_slot_function - Configure slot function - * - * @note - * Algorithm: - * - Set or reset the slot function based on set input - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * @param[in] set: Flag to set with OSI_ENABLE and reset with OSI_DISABLE - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, - nveu32_t set); -/** - * @brief osi_clear_rx_pkt_err_stats - Clear rx packet error stats. - * - * @note - * Algorithm: - * - This function will be invoked by OSD layer to clear the - * rx_crc_error mentioned in osi_dma->pkt_err_stats structure. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_txring_empty - Check if Txring is empty. - * - * @note - * Algorithm: - * - This function will be invoked by OSD layer to check if the Tx ring - * is empty or still has outstanding packets to be processed for Tx done. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: Channel number whose ring is to be checked. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured. - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 1 if ring is empty. - * @retval 0 if ring has outstanding packets. - */ -nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan); -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief osi_get_dma - Get pointer to osi_dma data structure. - * - * @note - * Algorithm: - * - Returns OSI DMA data structure. - * - * @pre OSD layer should use this as first API to get osi_dma pointer and - * use the same in remaning API invocation. - * - * @note - * Traceability Details: - * - * @usage - * - Allowed context for the API call - * - Interrupt handler: No - * - Signal handler: No - * - Thread safe: No - * - Async/Sync: Sync - * - Required Privileges: None - * - API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval valid and unique osi_dma pointer on success - * @retval NULL on failure. - */ -struct osi_dma_priv_data *osi_get_dma(void); -#endif /* INCLUDED_OSI_DMA_H */ diff --git a/include/osi_dma_txrx.h b/include/osi_dma_txrx.h deleted file mode 100644 index 97b3607..0000000 --- a/include/osi_dma_txrx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 INCLUDED_OSI_DMA_TXRX_H -#define INCLUDED_OSI_DMA_TXRX_H - -/** - * @addtogroup EQOS_Help Descriptor Helper MACROS - * - * @brief Helper macros for defining Tx/Rx descriptor count - * @{ - */ -#define OSI_EQOS_TX_DESC_CNT 1024U -#define OSI_EQOS_RX_DESC_CNT 1024U -#define OSI_MGBE_TX_DESC_CNT 4096U -#define OSI_MGBE_RX_DESC_CNT 4096U -#define OSI_MGBE_MAX_RX_DESC_CNT 16384U -/** @} */ - -/** TSO Header length divisor */ -#define OSI_TSO_HDR_LEN_DIVISOR 4U - -/** - * @addtogroup EQOS_Help1 Helper MACROS for descriptor index operations - * - * @brief Helper macros for incrementing or decrementing Tx/Rx descriptor index - * @{ - */ -/** Increment the tx descriptor index */ -#define INCR_TX_DESC_INDEX(idx, x) ((idx) = ((idx) + (1U)) & ((x) - 1U)) -/** Increment the rx descriptor index */ -#define INCR_RX_DESC_INDEX(idx, x) ((idx) = ((idx) + (1U)) & ((x) - 1U)) -#ifndef OSI_STRIPPED_LIB -/** Decrement the tx descriptor index */ -#define DECR_TX_DESC_INDEX(idx, x) ((idx) = ((idx) - (1U)) & ((x) - 1U)) -/** Decrement the rx descriptor index */ -#define DECR_RX_DESC_INDEX(idx, x) ((idx) = ((idx) - (1U)) & ((x) - 1U)) -#endif /* !OSI_STRIPPED_LIB */ -/** @} */ -#endif /* INCLUDED_OSI_DMA_TXRX_H */ diff --git a/include/osi_macsec.h b/include/osi_macsec.h deleted file mode 100644 index 8d98bd3..0000000 --- a/include/osi_macsec.h +++ /dev/null @@ -1,818 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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 INCLUDED_OSI_MACSEC_H -#define INCLUDED_OSI_MACSEC_H - -#include - -#ifdef MACSEC_SUPPORT -////////////////////////////////////////////////////////////////////////// - /* MACSEC OSI data structures */ -////////////////////////////////////////////////////////////////////////// - -/** - * @addtogroup TX/RX BYP/SCI LUT helpers macros - * - * @brief Helper macros for LUT programming - * @{ - */ -#define OSI_AN0_VALID OSI_BIT(0) -#define OSI_AN1_VALID OSI_BIT(1) -#define OSI_AN2_VALID OSI_BIT(2) -#define OSI_AN3_VALID OSI_BIT(3) -#define OSI_MAX_NUM_SA 4U -#define OSI_CURR_AN_MAX 3 -#define OSI_KEY_INDEX_MAX 31U -#define OSI_PN_MAX_DEFAULT 0xFFFFFFFFU -#define OSI_PN_THRESHOLD_DEFAULT 0xC0000000U -#define OSI_TCI_DEFAULT 0x1 -#define OSI_VLAN_IN_CLEAR_DEFAULT 0x0 -#define OSI_SC_INDEX_MAX 15U -#define OSI_ETHTYPE_LEN 2 -#define OSI_LUT_BYTE_PATTERN_MAX 4U -/* LUT byte pattern offset range 0-63 */ -#define OSI_LUT_BYTE_PATTERN_MAX_OFFSET 63U -/* VLAN PCP range 0-7 */ -#define OSI_VLAN_PCP_MAX 7U -/* VLAN ID range 1-4095 */ -#define OSI_VLAN_ID_MAX 4095U -#define OSI_LUT_SEL_BYPASS 0U -#define OSI_LUT_SEL_SCI 1U -#define OSI_LUT_SEL_SC_PARAM 2U -#define OSI_LUT_SEL_SC_STATE 3U -#define OSI_LUT_SEL_SA_STATE 4U -#define OSI_LUT_SEL_MAX 4U - -/* LUT input fields flags bit offsets */ -#define OSI_LUT_FLAGS_DA_BYTE0_VALID OSI_BIT(0) -#define OSI_LUT_FLAGS_DA_BYTE1_VALID OSI_BIT(1) -#define OSI_LUT_FLAGS_DA_BYTE2_VALID OSI_BIT(2) -#define OSI_LUT_FLAGS_DA_BYTE3_VALID OSI_BIT(3) -#define OSI_LUT_FLAGS_DA_BYTE4_VALID OSI_BIT(4) -#define OSI_LUT_FLAGS_DA_BYTE5_VALID OSI_BIT(5) -#define OSI_LUT_FLAGS_DA_VALID (OSI_BIT(0) | OSI_BIT(1) | OSI_BIT(2) |\ - OSI_BIT(3) | OSI_BIT(4) | OSI_BIT(5)) -#define OSI_LUT_FLAGS_SA_BYTE0_VALID OSI_BIT(6) -#define OSI_LUT_FLAGS_SA_BYTE1_VALID OSI_BIT(7) -#define OSI_LUT_FLAGS_SA_BYTE2_VALID OSI_BIT(8) -#define OSI_LUT_FLAGS_SA_BYTE3_VALID OSI_BIT(9) -#define OSI_LUT_FLAGS_SA_BYTE4_VALID OSI_BIT(10) -#define OSI_LUT_FLAGS_SA_BYTE5_VALID OSI_BIT(11) -#define OSI_LUT_FLAGS_SA_VALID (OSI_BIT(6) | OSI_BIT(7) | OSI_BIT(8) |\ - OSI_BIT(9) | OSI_BIT(10) | OSI_BIT(11)) -#define OSI_LUT_FLAGS_ETHTYPE_VALID OSI_BIT(12) -#define OSI_LUT_FLAGS_VLAN_PCP_VALID OSI_BIT(13) -#define OSI_LUT_FLAGS_VLAN_ID_VALID OSI_BIT(14) -#define OSI_LUT_FLAGS_VLAN_VALID OSI_BIT(15) -#define OSI_LUT_FLAGS_BYTE0_PATTERN_VALID OSI_BIT(16) -#define OSI_LUT_FLAGS_BYTE1_PATTERN_VALID OSI_BIT(17) -#define OSI_LUT_FLAGS_BYTE2_PATTERN_VALID OSI_BIT(18) -#define OSI_LUT_FLAGS_BYTE3_PATTERN_VALID OSI_BIT(19) -#define OSI_LUT_FLAGS_PREEMPT OSI_BIT(20) -#define OSI_LUT_FLAGS_PREEMPT_VALID OSI_BIT(21) -#define OSI_LUT_FLAGS_CONTROLLED_PORT OSI_BIT(22) -#define OSI_LUT_FLAGS_DVLAN_PKT OSI_BIT(23) -#define OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(24) -#define OSI_LUT_FLAGS_ENTRY_VALID OSI_BIT(31) -/** @} */ - -/** - * @addtogroup Generic table CONFIG register helpers macros - * - * @brief Helper macros for generic table CONFIG register programming - * @{ - */ -#define OSI_CTLR_SEL_TX 0U -#define OSI_CTLR_SEL_RX 1U -#define OSI_CTLR_SEL_MAX 1U -#define OSI_LUT_READ 0U -#define OSI_LUT_WRITE 1U -#define OSI_RW_MAX 1U -#define OSI_TABLE_INDEX_MAX 31U -#define OSI_BYP_LUT_MAX_INDEX OSI_TABLE_INDEX_MAX -#define OSI_SC_LUT_MAX_INDEX 15U -#define OSI_SA_LUT_MAX_INDEX OSI_TABLE_INDEX_MAX -/** @} */ - -/** - * @addtogroup Debug buffer table CONFIG register helpers macros - * - * @brief Helper macros for debug buffer table CONFIG register programming - * @{ - */ -#define OSI_DBG_TBL_READ OSI_LUT_READ -#define OSI_DBG_TBL_WRITE OSI_LUT_WRITE -/* Num of Tx debug buffers */ -#define OSI_TX_DBG_BUF_IDX_MAX 12U -/* Num of Rx debug buffers */ -#define OSI_RX_DBG_BUF_IDX_MAX 13U -/** flag - encoding various debug event bits */ -#define OSI_TX_DBG_LKUP_MISS_EVT OSI_BIT(0) -#define OSI_TX_DBG_AN_NOT_VALID_EVT OSI_BIT(1) -#define OSI_TX_DBG_KEY_NOT_VALID_EVT OSI_BIT(2) -#define OSI_TX_DBG_CRC_CORRUPT_EVT OSI_BIT(3) -#define OSI_TX_DBG_ICV_CORRUPT_EVT OSI_BIT(4) -#define OSI_TX_DBG_CAPTURE_EVT OSI_BIT(5) -#define OSI_RX_DBG_LKUP_MISS_EVT OSI_BIT(6) -#define OSI_RX_DBG_KEY_NOT_VALID_EVT OSI_BIT(7) -#define OSI_RX_DBG_REPLAY_ERR_EVT OSI_BIT(8) -#define OSI_RX_DBG_CRC_CORRUPT_EVT OSI_BIT(9) -#define OSI_RX_DBG_ICV_ERROR_EVT OSI_BIT(10) -#define OSI_RX_DBG_CAPTURE_EVT OSI_BIT(11) -/** @} */ - -/** - * @addtogroup AES ciphers - * - * @brief Helper macro's for AES ciphers - * @{ - */ -#define OSI_MACSEC_CIPHER_AES128 0U -#define OSI_MACSEC_CIPHER_AES256 1U -/** @} */ - -/** - * @addtogroup MACSEC Misc helper macro's - * - * @brief MACSEC Helper macro's - * @{ - */ -#define OSI_MACSEC_TX_EN OSI_BIT(0) -#define OSI_MACSEC_RX_EN OSI_BIT(1) -/* MACSEC SECTAG + ICV + 2B ethertype adds upto 34B */ -#define MACSEC_TAG_ICV_LEN 34U -/* MACSEC TZ key config cmd */ -#define OSI_MACSEC_CMD_TZ_CONFIG 0x1 -/* MACSEC TZ key table entries reset cmd */ -#define OSI_MACSEC_CMD_TZ_KT_RESET 0x2 -/** @} */ - -/** - * @brief Indicates different operations on MACSEC SA - */ -#define OSI_CREATE_SA 1U -#define OSI_ENABLE_SA 2U -#define OSI_DISABLE_SA 3U - -/** - * @brief MACSEC SA State LUT entry outputs structure - */ -struct osi_sa_state_outputs { - /** Indicates next PN to use */ - nveu32_t next_pn; - /** Indicates lowest PN to use */ - nveu32_t lowest_pn; -}; - -/** - * @brief MACSEC SC State LUT entry outputs structure - */ -struct osi_sc_state_outputs { - /** Indicates current AN to use */ - nveu32_t curr_an; -}; - -/** - * @brief MACSEC SC Param LUT entry outputs structure - */ -struct osi_sc_param_outputs { - /** Indicates Key index start */ - nveu32_t key_index_start; - /** PN max for given AN, after which HW will roll over to next AN */ - nveu32_t pn_max; - /** PN threshold to trigger irq when threshold is reached */ - nveu32_t pn_threshold; - /** Indidate PN window for engress packets */ - nveu32_t pn_window; - /** SC identifier */ - nveu8_t sci[OSI_SCI_LEN]; - /** Indicates SECTAG 3 TCI bits V, ES, SC - * Default TCI value V=1, ES=0, SC = 1 - */ - nveu8_t tci; - /** Indicates 1 bit VLAN IN CLEAR config */ - nveu8_t vlan_in_clear; -}; - -/** - * @brief MACSEC SCI LUT entry outputs structure - */ -struct osi_sci_lut_outputs { - /** Indicates SC index to use */ - nveu32_t sc_index; - /** SC identifier */ - nveu8_t sci[OSI_SCI_LEN]; - /** AN's valid */ - nveu32_t an_valid; -}; - -/** - * @brief MACSEC LUT config data structure - */ -struct osi_macsec_table_config { - /** Indicates controller select, Tx=0, Rx=1 */ - nveu16_t ctlr_sel; - /** Read or write operation select, Read=0, Write=1 */ - nveu16_t rw; - /** LUT entry index */ - nveu16_t index; -}; - -/** - * @brief MACSEC Key Table entry structure - */ -struct osi_kt_entry { - /** Indicates SAK key - max 256bit */ - nveu8_t sak[OSI_KEY_LEN_256]; - /** Indicates Hash-key */ - nveu8_t h[OSI_KEY_LEN_128]; -}; - -/** - * @brief MACSEC BYP/SCI LUT entry inputs structure - */ -struct osi_lut_inputs { - /** MAC DA to compare */ - nveu8_t da[OSI_ETH_ALEN]; - /** MAC SA to compare */ - nveu8_t sa[OSI_ETH_ALEN]; - /** Ethertype to compare */ - nveu8_t ethtype[OSI_ETHTYPE_LEN]; - /** 4-Byte pattern to compare */ - nveu8_t byte_pattern[OSI_LUT_BYTE_PATTERN_MAX]; - /** Offset for 4-Byte pattern to compare */ - nveu32_t byte_pattern_offset[OSI_LUT_BYTE_PATTERN_MAX]; - /** VLAN PCP to compare */ - nveu32_t vlan_pcp; - /** VLAN ID to compare */ - nveu32_t vlan_id; -}; - -/** - * @brief MACSEC LUT config data structure - */ -struct osi_macsec_lut_config { - /** Generic table config */ - struct osi_macsec_table_config table_config; - /** Indicates LUT to select - * 0: Bypass LUT - * 1: SCI LUT - * 2: SC PARAM LUT - * 3: SC STATE LUT - * 4: SA STATE LUT - */ - nveu16_t lut_sel; - /** flag - encoding various valid LUT bits for above fields */ - nveu32_t flags; - /** LUT inputs to use */ - struct osi_lut_inputs lut_in; - /** SCI LUT outputs */ - struct osi_sci_lut_outputs sci_lut_out; - /** SC Param LUT outputs */ - struct osi_sc_param_outputs sc_param_out; - /** SC State LUT outputs */ - struct osi_sc_state_outputs sc_state_out; - /** SA State LUT outputs */ - struct osi_sa_state_outputs sa_state_out; -}; - -/** - * @brief MACSEC Key Table config data structure - */ -struct osi_macsec_kt_config { - /** Generic table config */ - struct osi_macsec_table_config table_config; - /** Key Table entry config */ - struct osi_kt_entry entry; - /** Indicates key table entry valid or not, bit 31 */ - nveu32_t flags; -}; - -/** - * @brief MACSEC Debug buffer config data structure - */ -struct osi_macsec_dbg_buf_config { - /** Indicates Controller select, Tx=0, Rx=1 */ - nveu16_t ctlr_sel; - /** Read or write operation select, Read=0, Write=1 */ - nveu16_t rw; - /** Indicates debug data buffer */ - nveu32_t dbg_buf[4]; - /** flag - encoding various debug event bits */ - nveu32_t flags; - /** Indicates debug buffer index */ - nveu32_t index; -}; - -/** - * @brief MACSEC core operations structure - */ -struct osi_macsec_core_ops { - /** macsec init */ - nve32_t (*init)(struct osi_core_priv_data *const osi_core, - nveu32_t mtu); - /** macsec de-init */ - nve32_t (*deinit)(struct osi_core_priv_data *const osi_core); - /** Non Secure irq handler */ - void (*handle_ns_irq)(struct osi_core_priv_data *const osi_core); - /** Secure irq handler */ - void (*handle_s_irq)(struct osi_core_priv_data *const osi_core); - /** macsec lut config */ - nve32_t (*lut_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config); -#ifdef MACSEC_KEY_PROGRAM - /** macsec kt config */ - nve32_t (*kt_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); -#endif /* MACSEC_KEY_PROGRAM */ - /** macsec cipher config */ - nve32_t (*cipher_config)(struct osi_core_priv_data *const osi_core, - nveu32_t cipher); - /** macsec loopback config */ - nve32_t (*loopback_config)(struct osi_core_priv_data *const osi_core, - nveu32_t enable); - /** macsec enable */ - nve32_t (*macsec_en)(struct osi_core_priv_data *const osi_core, - nveu32_t enable); - /** macsec config SA in HW LUT */ - nve32_t (*config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu32_t enable, nveu16_t ctlr, - nveu16_t *kt_idx); - /** macsec read mmc counters */ - void (*read_mmc)(struct osi_core_priv_data *const osi_core); - /** macsec debug buffer config */ - nve32_t (*dbg_buf_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - /** macsec debug buffer config */ - nve32_t (*dbg_events_config)(struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - /** macsec get Key Index start for a given SCI */ - nve32_t (*get_sc_lut_key_index)(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr); - /** macsec set MTU size */ - nve32_t (*update_mtu)(struct osi_core_priv_data *const osi_core, - nveu32_t mtu); - -}; - -////////////////////////////////////////////////////////////////////////// - /* MACSEC OSI interface API prototypes */ -////////////////////////////////////////////////////////////////////////// - -/** - * @brief osi_init_macsec_ops - macsec initialize operations - * - * @note - * Algorithm: - * - If virtualization is enabled initialize virt ops - * - Else - * - If macsec base is null return -1 - * - initialize with macsec ops - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_macsec_init - Initialize the macsec controller - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Configure MTU, controller configs, interrupts, clear all LUT's and - * set BYP LUT entries for MKPDU and BC packets - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mtu: mtu to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu); - -/** - * @brief osi_macsec_deinit - De-Initialize the macsec controller - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Resets macsec global data structured and restores the mac confirguration - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_macsec_ns_isr - macsec non-secure irq handler - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - handles non-secure macsec interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval none - */ -void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_macsec_s_isr - macsec secure irq handler - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - handles secure macsec interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval none - */ -void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_macsec_config_lut - Read or write to macsec LUTs - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Reads or writes to MACSEC LUTs - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[out] lut_config: Pointer to the lut configuration - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config); - -/** - * @brief osi_macsec_config_kt - API to read or update the keys - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Read or write the keys - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] kt_config: Keys that needs to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config); - -/** - * @brief osi_macsec_cipher_config - API to update the cipher - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates cipher to use - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] cipher: Cipher suit to be used - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, - nveu32_t cipher); - -/** - * @brief osi_macsec_loopback - API to enable/disable macsec loopback - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Enables/disables macsec loopback - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] enable: parameter to enable or disable - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, - nveu32_t enable); - -/** - * @brief osi_macsec_en - API to enable/disable macsec - * - * @note - * Algorithm: - * - Return -1 if passed enable param is invalid - * - Return -1 if osi core or ops is null - * - Enables/disables macsec - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] enable: parameter to enable or disable - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, - nveu32_t enable); - -/** - * @brief osi_macsec_config - Updates SC or SA in the macsec - * - * @note - * Algorithm: - * - Return -1 if passed params are invalid - * - Return -1 if osi core or ops is null - * - Update/add/delete SC/SA - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] sc: Pointer to the sc that needs to be added/deleted/updated - * @param[in] ctlr: Controller selected - * @param[out] kt_idx: Pointer to the kt_index passed to OSD - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu32_t enable, nveu16_t ctlr, - nveu16_t *kt_idx); - -/** - * @brief osi_macsec_read_mmc - Updates the mmc counters - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates the mcc counters in osi_core structure - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[out] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core); - -/** - * @brief osi_macsec_config_dbg_buf - Reads the debug buffer captured - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Reads the dbg buffers captured - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[out] dbg_buf_config: dbg buffer data captured - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_dbg_buf( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - -/** - * @brief osi_macsec_dbg_events_config - Enables debug buffer events - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Enables specific events to capture debug buffers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] dbg_buf_config: dbg buffer data captured - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_dbg_events_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config); - -/** - * @brief osi_macsec_get_sc_lut_key_index - API to get key index for a given SCI - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - gets the key index for the given sci - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] sci: Pointer to sci that needs to be found - * @param[out] key_index: Pointer to key_index - * @param[in] ctlr: macsec controller selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_get_sc_lut_key_index( - struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr); - -/** - * @brief osi_macsec_update_mtu - Update the macsec mtu in run-time - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates the macsec mtu - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] mtu: mtu that needs to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, - nveu32_t mtu); - -#endif /* MACSEC_SUPPORT */ -#endif /* INCLUDED_OSI_MACSEC_H */ diff --git a/osi/common/common.h b/osi/common/common.h deleted file mode 100644 index d2b9082..0000000 --- a/osi/common/common.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 INCLUDED_COMMON_H -#define INCLUDED_COMMON_H - -#include "../osi/common/type.h" -#include - -/** - * @addtogroup Generic helper macros - * - * @brief These are Generic helper macros used at various places. - * @{ - */ -#define RETRY_COUNT 1000U -#define COND_MET 0 -#define COND_NOT_MET 1 -#define RETRY_DELAY 1U -/** @} */ - - -/** - * @brief Maximum number of supported MAC IP types (EQOS and MGBE) - */ -#define MAX_MAC_IP_TYPES 2U - -/** - * @brief osi_readl_poll_timeout - Periodically poll an address until - * a condition is met or a timeout occurs - * - * @param[in] addr: Memory mapped address. - * @param[in] val: Variable to read the value. - * @param[in] cond: Break condition (usually involving @val). - * @param[in] delay_us: Maximum time to sleep between reads in us. - * @param[in] retry: Retry count. - - * @note Physical address has to be memmory mapped. - * - * @retval 0 on success - * @retval -1 on failure. - */ -#define osi_readl_poll_timeout(addr, fn, val, cond, delay_us, retry) \ -({ \ - unsigned int count = 0; \ - while (count++ < retry) { \ - val = osi_readl((unsigned char *)addr); \ - if ((cond)) { \ - break; \ - } \ - fn(delay_us); \ - } \ - (cond) ? 0 : -1; \ -}) - -struct osi_core_priv_data; - -/** - * @brief osi_lock_init - Initialize lock to unlocked state. - * - * @note - * Algorithm: - * - Set lock to unlocked state. - * - * @param[in] lock - Pointer to lock to be initialized - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static inline void osi_lock_init(nveu32_t *lock) -{ - *lock = OSI_UNLOCKED; -} - -/** - * @brief osi_lock_irq_enabled - Spin lock. Busy loop till lock is acquired. - * - * @note - * Algorithm: - * - Atomic compare and swap operation till lock is held. - * - * @param[in] lock - Pointer to lock to be acquired. - * - * @note - * - Does not disable irq. Do not call this API to acquire any - * lock that is shared between top/bottom half. It will result in deadlock. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void osi_lock_irq_enabled(nveu32_t *lock) -{ - /* __sync_val_compare_and_swap(lock, old value, new value) returns the - * old value if successful. - */ - while (__sync_val_compare_and_swap(lock, OSI_UNLOCKED, OSI_LOCKED) != - OSI_UNLOCKED) { - /* Spinning. - * Will deadlock if any ISR tried to lock again. - */ - } -} - -/** - * @brief osi_unlock_irq_enabled - Release lock. - * - * @note - * Algorithm: - * - Atomic compare and swap operation to release lock. - * - * @param[in] lock - Pointer to lock to be released. - * - * @note - * - Does not disable irq. Do not call this API to release any - * lock that is shared between top/bottom half. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void osi_unlock_irq_enabled(nveu32_t *lock) -{ - if (__sync_val_compare_and_swap(lock, OSI_LOCKED, OSI_UNLOCKED) != - OSI_LOCKED) { - /* Do nothing. Already unlocked */ - } -} - -/** - * @brief osi_readl - Read a memory mapped register. - * - * @param[in] addr: Memory mapped address. - * - * @pre Physical address has to be memory mapped. - * - * @return Data from memory mapped register - success. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -static inline nveu32_t osi_readl(void *addr) -{ - return *(volatile nveu32_t *)addr; -} - -/** - * @brief osi_writel - Write to a memory mapped register. - * - * @param[in] val: Value to be written. - * @param[in] addr: Memory mapped address. - * - * @pre Physical address has to be memory mapped. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -static inline void osi_writel(nveu32_t val, void *addr) -{ - *(volatile nveu32_t *)addr = val; -} - -/** - * @brief osi_readla - Read a memory mapped register. - * - * @ note - * The difference between osi_readla & osi_readl is osi_core argument. - * In case of ethernet server, osi_core used to define policy for each VM. - * In case of non virtualization osi_core argument is ignored. - * - * @param[in] priv: Priv address. - * @param[in] addr: Memory mapped address. - * - * @note Physical address has to be memmory mapped. - * - * @return Data from memory mapped register - success. - */ -static inline nveu32_t osi_readla(OSI_UNUSED void *priv, void *addr) -{ - return *(volatile nveu32_t *)addr; -} - -/** - * - * @ note - * @brief osi_writela - Write to a memory mapped register. - * The difference between osi_writela & osi_writel is osi_core argument. - * In case of ethernet server, osi_core used to define policy for each VM. - * In case of non virtualization osi_core argument is ignored. - * - * @param[in] priv: Priv address. - * @param[in] val: Value to be written. - * @param[in] addr: Memory mapped address. - * - * @note Physical address has to be memmory mapped. - */ -static inline void osi_writela(OSI_UNUSED void *priv, nveu32_t val, void *addr) -{ - *(volatile nveu32_t *)addr = val; -} - -/** - * @brief validate_mac_ver_update_chans - Validates mac version and update chan - * - * @param[in] mac_ver: MAC version read. - * @param[out] max_chans: Maximum channel number. - * - * @note MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 - for not Valid MAC - * @retval 1 - for Valid MAC - */ -static inline nve32_t validate_mac_ver_update_chans(nveu32_t mac_ver, - nveu32_t *max_chans) -{ - switch (mac_ver) { - case OSI_EQOS_MAC_4_10: - case OSI_EQOS_MAC_5_00: - *max_chans = OSI_EQOS_XP_MAX_CHANS; - break; - case OSI_EQOS_MAC_5_30: - *max_chans = OSI_EQOS_MAX_NUM_CHANS; - break; - case OSI_MGBE_MAC_3_00: - case OSI_MGBE_MAC_3_10: - case OSI_MGBE_MAC_4_00: - *max_chans = OSI_MGBE_MAX_NUM_CHANS; - break; - default: - return 0; - } - - return 1; -} - -/** - * @brief osi_memset - osi memset - * - * @param[out] s: source that need to be set - * @param[in] c: value to fill in source - * @param[in] count: first n bytes of source - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void osi_memset(void *s, nveu32_t c, nveu64_t count) -{ - nveu8_t *xs = OSI_NULL; - nveu64_t temp = count; - - if (s == OSI_NULL) { - return; - } - xs = (nveu8_t *)s; - while (temp != 0UL) { - if (c < OSI_UCHAR_MAX) { - *xs = (nveu8_t)c; - xs++; - } - temp--; - } -} - -/** - * @brief osi_memcpy - osi memcpy - * - * @param[out] dest: destination pointer - * @param[in] src: source pointer - * @param[in] n: number bytes of source - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline nve32_t osi_memcpy(void *dest, void *src, nveu64_t n) -{ - nve8_t *csrc = (nve8_t *)src; - nve8_t *cdest = (nve8_t *)dest; - nveu64_t i = 0; - - if (src == OSI_NULL || dest == OSI_NULL) { - return -1; - } - for (i = 0; i < n; i++) { - cdest[i] = csrc[i]; - } - - return 0; -} - -static inline nve32_t osi_memcmp(void *dest, void *src, nve32_t n) -{ - nve32_t i; - nve8_t *csrc = (nve8_t *)src; - nve8_t *cdest = (nve8_t *)dest; - - if (src == OSI_NULL || dest == OSI_NULL) - return -1; - - for (i = 0; i < n; i++) { - if (csrc[i] < cdest[i]) { - return -1; - } else if (csrc[i] > cdest[i]) { - return 1; - } - } - return 0; -} -#endif diff --git a/osi/common/eqos_common.c b/osi/common/eqos_common.c deleted file mode 100644 index 0feb73f..0000000 --- a/osi/common/eqos_common.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2020, 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 "eqos_common.h" -#include "../osi/common/common.h" - -nveul64_t eqos_get_systime_from_mac(void *addr) -{ - nveul64_t ns1, ns2, ns = 0; - nveu32_t varmac_stnsr, temp1; - nveu32_t varmac_stsr; - - varmac_stnsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STNSR); - temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns1 = (nveul64_t)temp1; - - varmac_stsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STSR); - - varmac_stnsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STNSR); - temp1 = (varmac_stnsr & EQOS_MAC_STNSR_TSSS_MASK); - ns2 = (nveul64_t)temp1; - - /* if ns1 is greater than ns2, it means nsec counter rollover - * happened. In that case read the updated sec counter again - */ - if (ns1 >= ns2) { - varmac_stsr = osi_readl((nveu8_t *)addr + EQOS_MAC_STSR); - /* convert sec/high time value to nanosecond */ - if (varmac_stsr < UINT_MAX) { - ns = ns2 + (varmac_stsr * OSI_NSEC_PER_SEC); - } - } else { - /* convert sec/high time value to nanosecond */ - if (varmac_stsr < UINT_MAX) { - ns = ns1 + (varmac_stsr * OSI_NSEC_PER_SEC); - } - } - - return ns; -} - -nveu32_t eqos_is_mac_enabled(void *addr) -{ - nveu32_t enable = OSI_DISABLE; - nveu32_t reg; - - reg = osi_readl((nveu8_t *)addr + EQOS_MAC_MCR); - if ((reg & (EQOS_MCR_TE | EQOS_MCR_RE)) == - (EQOS_MCR_TE | EQOS_MCR_RE)) { - enable = OSI_ENABLE; - } - - return enable; -} diff --git a/osi/common/eqos_common.h b/osi/common/eqos_common.h deleted file mode 100644 index 6e982ec..0000000 --- a/osi/common/eqos_common.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020, 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 INCLUDED_EQOS_COMMON_H -#define INCLUDED_EQOS_COMMON_H - -#include - -/** - * @brief PTP Time read registers - * @{ - */ -#define EQOS_MAC_STSR 0x0B08 -#define EQOS_MAC_STNSR 0x0B0C -#define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU -/** @} */ - -/** - * @brief Common MAC MCR register and its bits - * @{ - */ -#define EQOS_MAC_MCR 0x0000 -#define EQOS_MCR_TE OSI_BIT(0) -#define EQOS_MCR_RE OSI_BIT(1) -/** @} */ - -/** - * @brief eqos_get_systime - Get system time from MAC - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nveul64_t eqos_get_systime_from_mac(void *addr); - -/** - * @brief eqos_is_mac_enabled - Checks if MAC is enabled or not. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval OSI_ENABLE if MAC enabled. - * @retval OSI_DISABLE otherwise. - */ -nveu32_t eqos_is_mac_enabled(void *addr); -#endif /* INCLUDED_EQOS_COMMON_H */ diff --git a/osi/common/include/local_common.h b/osi/common/include/local_common.h deleted file mode 100644 index 134cae0..0000000 --- a/osi/common/include/local_common.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2020-2021, 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 LOCAL_COMMON_H -#define LOCAL_COMMON_H - -#include - -/** - * @brief TX timestamp helper MACROS - * @{ - */ -#define CHAN_START_POSITION 6U -#define PKT_ID_CNT ((nveu32_t)1 << CHAN_START_POSITION) -/* First 6 bytes of idx and last 4 bytes of chan(+1 to avoid pkt_id to be 0) */ -#define GET_TX_TS_PKTID(idx, c) (((++(idx)) & (PKT_ID_CNT - 1U)) | \ - (((c) + 1U) << CHAN_START_POSITION)) -/** @} */ - -/** - *@brief div_u64_rem - updates remainder and returns Quotient - * - * @note - * Algorithm: - * - Dividend will be divided by divisor and stores the - * remainder value and returns quotient - * - * @param[in] dividend: Dividend value - * @param[in] divisor: Divisor value - * @param[out] remain: Remainder - * - * @pre MAC IP should be out of reset and need to be initialized as the - * requirements - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval Quotient - */ -nveu64_t div_u64_rem(nveu64_t dividend, nveu64_t divisor, - nveu64_t *remain); - -/** - * @brief common_get_systime_from_mac - Get system time - * - * @param[in] addr: Address of base register. - * @param[in] mac: MAC HW type. - * @param[out] sec: Value read in Seconds. - * @param[out] nsec: Value read in Nano seconds. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -void common_get_systime_from_mac(void *addr, nveu32_t mac, - nveu32_t *sec, nveu32_t *nsec); - -/** - * @brief common_is_mac_enabled - Checks if MAC is enabled or not. - * - * @param[in] addr: Address of base register. - * @param[in] mac: MAC HW type. - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval OSI_ENABLE if MAC enabled. - * @retval OSI_DISABLE otherwise. - */ -nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac); -#endif /* LOCAL_COMMON_H */ diff --git a/osi/common/mgbe_common.c b/osi/common/mgbe_common.c deleted file mode 100644 index 0ca6879..0000000 --- a/osi/common/mgbe_common.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2020-2021, 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 "../osi/common/common.h" -#include "mgbe_common.h" - -/** - * @brief mgbe_get_systime_from_mac - Get system time from MAC - * - * Algorithm: Get current system time - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -nveul64_t mgbe_get_systime_from_mac(void *addr) -{ - nveul64_t ns1, ns2, ns = 0; - nveu32_t varmac_stnsr, temp1; - nveu32_t varmac_stsr; - - varmac_stnsr = osi_readl((nveu8_t *)addr + MGBE_MAC_STNSR); - temp1 = (varmac_stnsr & MGBE_MAC_STNSR_TSSS_MASK); - ns1 = (nveul64_t)temp1; - - varmac_stsr = osi_readl((nveu8_t *)addr + MGBE_MAC_STSR); - - varmac_stnsr = osi_readl((nveu8_t *)addr + MGBE_MAC_STNSR); - temp1 = (varmac_stnsr & MGBE_MAC_STNSR_TSSS_MASK); - ns2 = (nveul64_t)temp1; - - /* if ns1 is greater than ns2, it means nsec counter rollover - * happened. In that case read the updated sec counter again - */ - if (ns1 >= ns2) { - varmac_stsr = osi_readl((nveu8_t *)addr + MGBE_MAC_STSR); - /* convert sec/high time value to nanosecond */ - if (varmac_stsr < UINT_MAX) { - ns = ns2 + (varmac_stsr * OSI_NSEC_PER_SEC); - } - } else { - /* convert sec/high time value to nanosecond */ - if (varmac_stsr < UINT_MAX) { - ns = ns1 + (varmac_stsr * OSI_NSEC_PER_SEC); - } - } - - return ns; -} - -nveu32_t mgbe_is_mac_enabled(void *addr) -{ - nveu32_t enable = OSI_DISABLE; - nveu32_t reg; - - reg = osi_readl((nveu8_t *)addr + MGBE_MAC_TX); - if ((reg & (MGBE_MCR_TE)) == MGBE_MCR_TE) { - enable = OSI_ENABLE; - } - - return enable; -} diff --git a/osi/common/mgbe_common.h b/osi/common/mgbe_common.h deleted file mode 100644 index 7ebffeb..0000000 --- a/osi/common/mgbe_common.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2020-2021, 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 INCLUDED_MGBE_COMMON_H -#define INCLUDED_MGBE_COMMON_H - -/** - * @addtogroup MGBE-MAC MGBE MAC common HW feature registers - * - * @{ - */ -#define MGBE_MAC_STSR 0x0D08 -#define MGBE_MAC_STNSR 0x0D0C -#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU - -#define MGBE_MAC_TX 0x0000 -#define MGBE_MCR_TE OSI_BIT(0) -/** @} */ - - -nveul64_t mgbe_get_systime_from_mac(void *addr); -nveu32_t mgbe_is_mac_enabled(void *addr); - -#endif /* INCLUDED_MGBE_COMMON_H */ diff --git a/osi/common/osi_common.c b/osi/common/osi_common.c deleted file mode 100644 index 18df8ff..0000000 --- a/osi/common/osi_common.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2018-2021, 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 "eqos_common.h" -#include "mgbe_common.h" -#include "../osi/common/common.h" - -void common_get_systime_from_mac(void *addr, nveu32_t mac, nveu32_t *sec, - nveu32_t *nsec) -{ - nveu64_t temp; - nveu64_t remain; - nveul64_t ns; - typedef nveul64_t (*get_time)(void *addr); - get_time i_ops[MAX_MAC_IP_TYPES] = { - eqos_get_systime_from_mac, mgbe_get_systime_from_mac - }; - - ns = i_ops[mac](addr); - - temp = div_u64_rem((nveu64_t)ns, OSI_NSEC_PER_SEC, &remain); - if (temp < UINT_MAX) { - *sec = (nveu32_t)temp; - } else { - /* do nothing here */ - } - if (remain < UINT_MAX) { - *nsec = (nveu32_t)remain; - } else { - /* do nothing here */ - } -} - -nveu32_t common_is_mac_enabled(void *addr, nveu32_t mac) -{ - typedef nveu32_t (*mac_enable_arr)(void *addr); - mac_enable_arr i_ops[MAX_MAC_IP_TYPES] = { - eqos_is_mac_enabled, mgbe_is_mac_enabled - }; - - return i_ops[mac](addr); -} - -nveu64_t div_u64_rem(nveu64_t dividend, nveu64_t divisor, - nveu64_t *remain) -{ - nveu64_t ret = 0; - - if (divisor != 0U) { - *remain = dividend % divisor; - ret = dividend / divisor; - } else { - ret = 0; - } - - return ret; -} diff --git a/osi/common/type.h b/osi/common/type.h deleted file mode 100644 index d2ed7c7..0000000 --- a/osi/common/type.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2020, 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 INCLUDED_TYPE_H -#define INCLUDED_TYPE_H -/* - * @addtogroup typedef related info - * - * @brief typedefs that indicate size and signness - * @{ - */ -/* Following added to avoid misraC 4.6 - * Here we are defining intermediate type - */ -/** intermediate type for unsigned int */ -typedef unsigned int my_uint32_t; -/** intermediate type for int */ -typedef int my_int32_t; -/** intermediate type for unsigned short */ -typedef unsigned short my_uint16_t; -/** intermediate type for short */ -typedef short my_int16_t; -/** intermediate type for char */ -typedef char my_int8_t; -/** intermediate type for unsigned char */ -typedef unsigned char my_uint8_t; -/** intermediate type for unsigned long long */ -typedef unsigned long long my_ulint_64; -/** intermediate type for long */ -typedef unsigned long my_uint64_t; - -/* Actual type used in code */ -/** typedef equivalent to unsigned int */ -typedef my_uint32_t nveu32_t; -/** typedef equivalent to int */ -typedef my_int32_t nve32_t; -/** typedef equivalent to unsigned short */ -typedef my_uint16_t nveu16_t; -/** typedef equivalent to short */ -typedef my_int16_t nve16_t; -/** typedef equivalent to char */ -typedef my_int8_t nve8_t; -/** typedef equivalent to unsigned char */ -typedef my_uint8_t nveu8_t; -/** typedef equivalent to unsigned long long */ -typedef my_ulint_64 nveul64_t; -/** typedef equivalent to long long */ -typedef my_uint64_t nveu64_t; -/** @} */ - -#endif /* INCLUDED_TYPE_H */ diff --git a/osi/core/Makefile.interface.tmk b/osi/core/Makefile.interface.tmk deleted file mode 100644 index 4637979..0000000 --- a/osi/core/Makefile.interface.tmk +++ /dev/null @@ -1,38 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 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. -# -# libnvethernetrm interface makefile fragment -# -############################################################################### - -ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION -NV_INTERFACE_NAME := nvethernetrm -NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME) -NV_INTERFACE_PUBLIC_INCLUDES := \ - ./include -endif - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 8 -# End: -# vi: set tabstop=8 noexpandtab: diff --git a/osi/core/Makefile.tmk b/osi/core/Makefile.tmk deleted file mode 100644 index 521160a..0000000 --- a/osi/core/Makefile.tmk +++ /dev/null @@ -1,75 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 2019-2022, 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. -# -############################################################################### - -ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION -include $(NV_BUILD_START_COMPONENT) - -NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 - -NV_COMPONENT_NAME := nvethernetrm -NV_COMPONENT_OWN_INTERFACE_DIR := . -NV_COMPONENT_SOURCES := \ - eqos_core.c \ - eqos_mmc.c \ - osi_core.c \ - vlan_filter.c \ - osi_hal.c \ - ivc_core.c \ - frp.c \ - mgbe_core.c \ - xpcs.c \ - mgbe_mmc.c \ - debug.c \ - core_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/mgbe_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/core/macsec.c - -#NV_COMPONENT_CFLAGS += -DMACSEC_SUPPORT -#NV_COMPONENT_CFLAGS += -DMACSEC_KEY_PROGRAM -#NV_COMPONENT_CFLAGS += -DDEBUG_MACSEC - -ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_LINUX),1) - NV_COMPONENT_CFLAGS += -DLINUX_OS -else ifeq ($(NV_BUILD_CONFIGURATION_OS_IS_QNX),1) - NV_COMPONENT_CFLAGS += -DQNX_OS -endif - -ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) -NV_COMPONENT_CFLAGS += -DOSI_DEBUG -endif - -NV_COMPONENT_INCLUDES := \ - $(NV_SOURCE)/nvethernetrm/include \ - $(NV_SOURCE)/nvethernetrm/osi/common/include - -include $(NV_BUILD_SHARED_LIBRARY) -endif - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 8 -# End: -# vi: set tabstop=8 noexpandtab: diff --git a/osi/core/core_common.c b/osi/core/core_common.c deleted file mode 100644 index 0d218a6..0000000 --- a/osi/core/core_common.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2022, 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 "../osi/common/common.h" -#include "core_common.h" -#include "mgbe_core.h" -#include "eqos_core.h" - -/** - * @brief hw_est_read - indirect read the GCL to Software own list - * (SWOL) - * - * @param[in] base: MAC base IOVA address. - * @param[in] addr_val: Address offset for indirect write. - * @param[in] data: Data to be written at offset. - * @param[in] gcla: Gate Control List Address, 0 for ETS register. - * 1 for GCL memory. - * @param[in] bunk: Memory bunk from which vlaues will be read. Possible - * value 0 or 1. - * @param[in] mac: MAC index - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t hw_est_read(struct osi_core_priv_data *osi_core, - nveu32_t addr_val, nveu32_t *data, - nveu32_t gcla, nveu32_t bunk, - nveu32_t mac) -{ - nve32_t retry = 1000; - nveu32_t val = 0U; - nve32_t ret; - const nveu32_t MTL_EST_GCL_CONTROL[MAX_MAC_IP_TYPES] = { - EQOS_MTL_EST_GCL_CONTROL, MGBE_MTL_EST_GCL_CONTROL}; - const nveu32_t MTL_EST_DATA[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_DATA, - MGBE_MTL_EST_DATA}; - - *data = 0U; - val &= ~MTL_EST_ADDR_MASK; - val |= (gcla == 1U) ? 0x0U : MTL_EST_GCRR; - val |= MTL_EST_SRWO | MTL_EST_R1W0 | MTL_EST_DBGM | bunk | addr_val; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MTL_EST_GCL_CONTROL[mac]); - - while (--retry > 0) { - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MTL_EST_GCL_CONTROL[mac]); - if ((val & MTL_EST_SRWO) == MTL_EST_SRWO) { - continue; - } - osi_core->osd_ops.udelay(OSI_DELAY_1US); - - break; - } - - if (((val & MTL_EST_ERR0) == MTL_EST_ERR0) || - (retry <= 0)) { - ret = -1; - goto err; - } - - *data = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MTL_EST_DATA[mac]); - ret = 0; -err: - return ret; -} - -/** - * @brief eqos_gcl_validate - validate GCL from user - * - * Algorithm: validate GCL size and width of time interval value - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est: Configuration input argument. - * @param[in] mac: MAC index - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est, - const nveu32_t *btr, nveu32_t mac) -{ - const struct core_local *l_core = (struct core_local *)osi_core; - const nveu32_t PTP_CYCLE_8[MAX_MAC_IP_TYPES] = {EQOS_8PTP_CYCLE, - MGBE_8PTP_CYCLE}; - const nveu32_t MTL_EST_CONTROL[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CONTROL, - MGBE_MTL_EST_CONTROL}; - const nveu32_t MTL_EST_STATUS[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_STATUS, - MGBE_MTL_EST_STATUS}; - const nveu32_t MTL_EST_BTR_LOW[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_BTR_LOW, - MGBE_MTL_EST_BTR_LOW}; - const nveu32_t MTL_EST_BTR_HIGH[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_BTR_HIGH, - MGBE_MTL_EST_BTR_HIGH}; - const nveu32_t MTL_EST_CTR_LOW[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CTR_LOW, - MGBE_MTL_EST_CTR_LOW}; - const nveu32_t MTL_EST_CTR_HIGH[MAX_MAC_IP_TYPES] = {EQOS_MTL_EST_CTR_HIGH, - MGBE_MTL_EST_CTR_HIGH}; - nveu32_t i; - nveu64_t sum_ti = 0U; - nveu64_t sum_tin = 0U; - nveu64_t ctr = 0U; - nveu64_t btr_new = 0U; - nveu32_t btr_l, btr_h, ctr_l, ctr_h; - nveu32_t bunk = 0U; - nveu32_t est_status; - nveu64_t old_btr, old_ctr; - nve32_t ret; - nveu32_t val = 0U; - nveu64_t rem = 0U; - const struct est_read hw_read_arr[4] = { - {&btr_l, MTL_EST_BTR_LOW[mac]}, - {&btr_h, MTL_EST_BTR_HIGH[mac]}, - {&ctr_l, MTL_EST_CTR_LOW[mac]}, - {&ctr_h, MTL_EST_CTR_HIGH[mac]}}; - - if (est->llr > l_core->gcl_dep) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "input argument more than GCL depth\n", - (nveul64_t)est->llr); - return -1; - } - - ctr = ((nveu64_t)est->ctr[1] * OSI_NSEC_PER_SEC) + est->ctr[0]; - btr_new = (((nveu64_t)btr[1] + est->btr_offset[1]) * OSI_NSEC_PER_SEC) + - (btr[0] + est->btr_offset[0]); - for (i = 0U; i < est->llr; i++) { - if (est->gcl[i] <= l_core->gcl_width_val) { - sum_ti += ((nveu64_t)est->gcl[i] & l_core->ti_mask); - if ((sum_ti > ctr) && - ((ctr - sum_tin) >= PTP_CYCLE_8[mac])) { - continue; - } else if (((ctr - sum_ti) != 0U) && - ((ctr - sum_ti) < PTP_CYCLE_8[mac])) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_INVALID, - "CTR issue due to trancate\n", - (nveul64_t)i); - return -1; - } else { - //do nothing - } - sum_tin = sum_ti; - continue; - } - - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "validation of GCL entry failed\n", - (nveul64_t)i); - return -1; - } - - /* Check for BTR in case of new ETS while current GCL enabled */ - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MTL_EST_CONTROL[mac]); - if ((val & MTL_EST_CONTROL_EEST) != MTL_EST_CONTROL_EEST) { - return 0; - } - - /* Read EST_STATUS for bunk */ - est_status = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MTL_EST_STATUS[mac]); - if ((est_status & MTL_EST_STATUS_SWOL) == 0U) { - bunk = MTL_EST_DBGB; - } - - /* Read last BTR and CTR */ - for (i = 0U; i < (sizeof(hw_read_arr) / sizeof(hw_read_arr[0])); i++) { - ret = hw_est_read(osi_core, hw_read_arr[i].addr, - hw_read_arr[i].var, OSI_DISABLE, - bunk, mac); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Reading failed for index\n", - (nveul64_t)i); - return ret; - } - } - - old_btr = btr_l + ((nveu64_t)btr_h * OSI_NSEC_PER_SEC); - old_ctr = ctr_l + ((nveu64_t)ctr_h * OSI_NSEC_PER_SEC); - if (old_btr > btr_new) { - rem = (old_btr - btr_new) % old_ctr; - if ((rem != OSI_NONE) && (rem < PTP_CYCLE_8[mac])) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid BTR", (nveul64_t)rem); - return -1; - } - } else if (btr_new > old_btr) { - rem = (btr_new - old_btr) % old_ctr; - if ((rem != OSI_NONE) && (rem < PTP_CYCLE_8[mac])) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid BTR", (nveul64_t)rem); - return -1; - } - } else { - // Nothing to do - } - - return 0; -} diff --git a/osi/core/core_common.h b/osi/core/core_common.h deleted file mode 100644 index 81b69a7..0000000 --- a/osi/core/core_common.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2022, 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 INCLUDED_CORE_COMMON_H -#define INCLUDED_CORE_COMMON_H - -#include "core_local.h" -#define MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11) | \ - OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15) | \ - OSI_BIT(16) | (17) | \ - OSI_BIT(18) | OSI_BIT(19)) -#define MTL_EST_SRWO OSI_BIT(0) -#define MTL_EST_R1W0 OSI_BIT(1) -#define MTL_EST_GCRR OSI_BIT(2) -#define MTL_EST_DBGM OSI_BIT(4) -#define MTL_EST_DBGB OSI_BIT(5) -#define MTL_EST_ERR0 OSI_BIT(20) -#define MTL_EST_CONTROL_EEST OSI_BIT(0) -#define MTL_EST_STATUS_SWOL OSI_BIT(7) - -/** - * @addtogroup typedef related info - * - * @brief typedefs that indeicates variable address and memory addr - * @{ - */ - -struct est_read { - /* variable pointer */ - nveu32_t *var; - /* memory register/address offset */ - nveu32_t addr; -}; - -/** @} */ - -nve32_t gcl_validate(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est, - const nveu32_t *btr, nveu32_t mac); -#endif /* INCLUDED_CORE_COMMON_H */ diff --git a/osi/core/core_local.h b/osi/core/core_local.h deleted file mode 100644 index d616c53..0000000 --- a/osi/core/core_local.h +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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 INCLUDED_CORE_LOCAL_H -#define INCLUDED_CORE_LOCAL_H - -#include -#include - -/** - * @brief Maximum number of OSI core instances. - */ -#ifndef MAX_CORE_INSTANCES -#define MAX_CORE_INSTANCES 10U -#endif - -/** - * @brief Maximum number of interface operations. - */ -#define MAX_INTERFACE_OPS 2U - -/** - * @brief Maximum number of timestamps stored in OSI from HW FIFO. - */ -#define MAX_TX_TS_CNT (PKT_ID_CNT * OSI_MGBE_MAX_NUM_CHANS) - -/** - * interface core ops - */ -struct if_core_ops { - /** Interface function called to initialize MAC and MTL registers */ - nve32_t (*if_core_init)(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, nveu32_t rx_fifo_size); - /** Interface function called to deinitialize MAC and MTL registers */ - nve32_t (*if_core_deinit)(struct osi_core_priv_data *const osi_core); - /** Interface function called to write into a PHY reg over MDIO bus */ - nve32_t (*if_write_phy_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg, - const nveu16_t phydata); - /** Interface function called to read a PHY reg over MDIO bus */ - nve32_t (*if_read_phy_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg); - /** Initialize Interface core operations */ - nve32_t (*if_init_core_ops)(struct osi_core_priv_data *const osi_core); - /** Interface function called to handle runtime commands */ - nve32_t (*if_handle_ioctl)(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data); -}; - -/** - * @brief Initialize MAC & MTL core operations. - */ -struct core_ops { - /** Called to poll for software reset bit */ - nve32_t (*poll_for_swr)(struct osi_core_priv_data *const osi_core); - /** Called to initialize MAC and MTL registers */ - nve32_t (*core_init)(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_fifo_size, - const nveu32_t rx_fifo_size); - /** Called to deinitialize MAC and MTL registers */ - void (*core_deinit)(struct osi_core_priv_data *const osi_core); - /** Called to start MAC Tx and Rx engine */ - void (*start_mac)(struct osi_core_priv_data *const osi_core); - /** Called to stop MAC Tx and Rx engine */ - void (*stop_mac)(struct osi_core_priv_data *const osi_core); - /** Called to handle common interrupt */ - void (*handle_common_intr)(struct osi_core_priv_data *const osi_core); - /** Called to set the mode at MAC (full/duplex) */ - nve32_t (*set_mode)(struct osi_core_priv_data *const osi_core, - const nve32_t mode); - /** Called to set the speed at MAC */ - nve32_t (*set_speed)(struct osi_core_priv_data *const osi_core, - const nve32_t speed); - /** Called to do pad caliberation */ - nve32_t (*pad_calibrate)(struct osi_core_priv_data *const osi_core); - /** Called to configure MTL RxQ to forward the err pkt */ - nve32_t (*config_fw_err_pkts)(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, - const nveu32_t fw_err); - /** Called to configure Rx Checksum offload engine */ - nve32_t (*config_rxcsum_offload)( - struct osi_core_priv_data *const osi_core, - const nveu32_t enabled); - /** Called to config mac packet filter */ - nve32_t (*config_mac_pkt_filter_reg)( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter); - /** Called to update MAC address 1-127 */ - nve32_t (*update_mac_addr_low_high_reg)( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter); - /** Called to configure l3/L4 filter */ - nve32_t (*config_l3_l4_filter_enable)( - struct osi_core_priv_data *const osi_core, - const nveu32_t enable); - /** Called to configure L3 filter */ - nve32_t (*config_l3_filters)(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu32_t enb_dis, - const nveu32_t ipv4_ipv6_match, - const nveu32_t src_dst_addr_match, - const nveu32_t perfect_inverse_match, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan); - /** Called to update ip4 src or desc address */ - nve32_t (*update_ip4_addr)(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu8_t addr[], - const nveu32_t src_dst_addr_match); - /** Called to update ip6 address */ - nve32_t (*update_ip6_addr)(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t addr[]); - /** Called to configure L4 filter */ - nve32_t (*config_l4_filters)(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu32_t enb_dis, - const nveu32_t tcp_udp_match, - const nveu32_t src_dst_port_match, - const nveu32_t perfect_inverse_match, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan); - /** Called to update L4 Port for filter packet */ - nve32_t (*update_l4_port_no)(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t port_no, - const nveu32_t src_dst_port_match); - /** Called to set the addend value to adjust the time */ - nve32_t (*config_addend)(struct osi_core_priv_data *const osi_core, - const nveu32_t addend); - /** Called to adjust the mac time */ - nve32_t (*adjust_mactime)(struct osi_core_priv_data *const osi_core, - const nveu32_t sec, - const nveu32_t nsec, - const nveu32_t neg_adj, - const nveu32_t one_nsec_accuracy); - /** Called to set current system time to MAC */ - nve32_t (*set_systime_to_mac)(struct osi_core_priv_data *const osi_core, - const nveu32_t sec, - const nveu32_t nsec); - /** Called to configure the TimeStampControl register */ - void (*config_tscr)(struct osi_core_priv_data *const osi_core, - const nveu32_t ptp_filter); - /** Called to configure the sub second increment register */ - void (*config_ssir)(struct osi_core_priv_data *const osi_core, - const nveu32_t ptp_clock); - /** Called to configure the PTP RX packets Queue */ - nve32_t (*config_ptp_rxq)(struct osi_core_priv_data *const osi_core, - const unsigned int rxq_idx, - const unsigned int enable); - /** Called to update MMC counter from HW register */ - void (*read_mmc)(struct osi_core_priv_data *const osi_core); - /** Called to write into a PHY reg over MDIO bus */ - nve32_t (*write_phy_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg, - const nveu16_t phydata); - /** Called to read from a PHY reg over MDIO bus */ - nve32_t (*read_phy_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg); - /** Called to read reg */ - nveu32_t (*read_reg)(struct osi_core_priv_data *const osi_core, - const nve32_t reg); - /** Called to write reg */ - nveu32_t (*write_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t val, - const nve32_t reg); -#ifdef MACSEC_SUPPORT - /** Called to read macsec reg */ - nveu32_t (*read_macsec_reg)(struct osi_core_priv_data *const osi_core, - const nve32_t reg); - /** Called to write macsec reg */ - nveu32_t (*write_macsec_reg)(struct osi_core_priv_data *const osi_core, - const nveu32_t val, - const nve32_t reg); -#endif /* MACSEC_SUPPORT */ -#ifndef OSI_STRIPPED_LIB - /** Called periodically to read and validate safety critical - * registers against last written value */ - nve32_t (*validate_regs)(struct osi_core_priv_data *const osi_core); - /** Called to flush MTL Tx queue */ - nve32_t (*flush_mtl_tx_queue)(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx); - /** Called to set av parameter */ - nve32_t (*set_avb_algorithm)(struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *const avb); - /** Called to get av parameter */ - nve32_t (*get_avb_algorithm)(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb); - /** Called to configure the MTL to forward/drop tx status */ - nve32_t (*config_tx_status)(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status); - /** Called to configure the MAC rx crc */ - nve32_t (*config_rx_crc_check)( - struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk); - /** Called to configure the MAC flow control */ - nve32_t (*config_flow_control)( - struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl); - /** Called to enable/disable HW ARP offload feature */ - nve32_t (*config_arp_offload)(struct osi_core_priv_data *const osi_core, - const nveu32_t enable, - const nveu8_t *ip_addr); - /** Called to configure VLAN filtering */ - nve32_t (*config_vlan_filtering)( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_enb_dis, - const nveu32_t perfect_hash_filtering, - const nveu32_t perfect_inverse_match); - /** Called to reset MMC HW counter structure */ - void (*reset_mmc)(struct osi_core_priv_data *const osi_core); - /** Called to configure EEE Tx LPI */ - void (*configure_eee)(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_lpi_enabled, - const nveu32_t tx_lpi_timer); - /** Called to save MAC register space during SoC suspend */ - nve32_t (*save_registers)(struct osi_core_priv_data *const osi_core); - /** Called to restore MAC control registers during SoC resume */ - nve32_t (*restore_registers)(struct osi_core_priv_data *const osi_core); - /** Called to set MDC clock rate for MDIO operation */ - void (*set_mdc_clk_rate)(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate); - /** Called to configure MAC in loopback mode */ - nve32_t (*config_mac_loopback)( - struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode); -#endif /* !OSI_STRIPPED_LIB */ - /** Called to get HW features */ - nve32_t (*get_hw_features)(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat); - /** Called to configure RSS for MAC */ - nve32_t (*config_rss)(struct osi_core_priv_data *osi_core); - /** Called to update GCL config */ - int (*hw_config_est)(struct osi_core_priv_data *const osi_core, - struct osi_est_config *const est); - /** Called to update FPE config */ - int (*hw_config_fpe)(struct osi_core_priv_data *const osi_core, - struct osi_fpe_config *const fpe); - /** Called to configure FRP engine */ - int (*config_frp)(struct osi_core_priv_data *const osi_core, - const unsigned int enabled); - /** Called to update FRP Instruction Table entry */ - int (*update_frp_entry)(struct osi_core_priv_data *const osi_core, - const unsigned int pos, - struct osi_core_frp_data *const data); - /** Called to update FRP NVE and */ - int (*update_frp_nve)(struct osi_core_priv_data *const osi_core, - const unsigned int nve); - /** Called to configure HW PTP offload feature */ - int (*config_ptp_offload)(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config); -#ifdef MACSEC_SUPPORT - void (*macsec_config_mac)(struct osi_core_priv_data *const osi_core, - const nveu32_t enable); -#endif /* MACSEC_SUPPORT */ - int (*ptp_tsc_capture)(struct osi_core_priv_data *const osi_core, - struct osi_core_ptp_tsc_data *data); -#ifdef HSI_SUPPORT - /** Interface function called to initialize HSI */ - int (*core_hsi_configure)(struct osi_core_priv_data *const osi_core, - const nveu32_t enable); -#endif -}; - -/** - * @brief constant values for drift MAC to MAC sync. - */ -#ifndef DRIFT_CAL -#define DRIFT_CAL 1 -#define I_COMPONENT_BY_10 3 -#define P_COMPONENT_BY_10 7 -#define WEIGHT_BY_10 10 -#define CONST_FACTOR 8 //(1sec/125ns) -#define MAX_FREQ 85000000LL -#endif -#define EQOS_SEC_OFFSET 0xB08 -#define EQOS_NSEC_OFFSET 0xB0C -#define MGBE_SEC_OFFSET 0xD08 -#define MGBE_NSEC_OFFSET 0xD0C -#define ETHER_NSEC_MASK 0x7FFFFFFF -#define SERVO_STATS_0 0 -#define SERVO_STATS_1 1 -#define SERVO_STATS_2 2 - -/** - * @brief servo data structure. - */ -struct core_ptp_servo { - /** Offset/drift array to maintain current and last value */ - nvel64_t offset[2]; - /** Target MAC HW time counter array to maintain current and last - * value - */ - nvel64_t local[2]; - /* Servo state. initialized with 0. This states are used to monitor - * if there is sudden change in offset */ - nveu32_t count; - /* Accumulated freq drift */ - nvel64_t drift; - /* P component */ - nvel64_t const_p; - /* I component */ - nvel64_t const_i; - /* Last know ppb */ - nvel64_t last_ppb; - /* MAC to MAC locking to access HW time register within OSI calls */ - nveu32_t m2m_lock; -}; - -/** - * @brief Core local data structure. - */ -struct core_local { - /** OSI Core data variable */ - struct osi_core_priv_data osi_core; - /** Core local operations variable */ - struct core_ops *ops_p; - /** interface core local operations variable */ - struct if_core_ops *if_ops_p; - /** structure to store tx time stamps */ - struct osi_core_tx_ts ts[MAX_TX_TS_CNT]; - /** Flag to represent initialization done or not */ - nveu32_t init_done; - /** Flag to represent infterface initialization done or not */ - nveu32_t if_init_done; - /** Magic number to validate osi core pointer */ - nveu64_t magic_num; - /** This is the head node for PTP packet ID queue */ - struct osi_core_tx_ts tx_ts_head; - /** Maximum number of queues/channels */ - nveu32_t max_chans; - /** GCL depth supported by HW */ - nveu32_t gcl_dep; - /** Max GCL width (time + gate) value supported by HW */ - nveu32_t gcl_width_val; - /** TS lock */ - nveu32_t ts_lock; - /** Controller mac to mac role */ - nveu32_t ether_m2m_role; - /** Servo structure */ - struct core_ptp_servo serv; - /** HW comeout from reset successful OSI_ENABLE else OSI_DISABLE */ - nveu32_t hw_init_successful; - /** Dynamic MAC to MAC time sync control for secondary interface */ - nveu32_t m2m_tsync; - /** control pps output signal */ - nveu32_t pps_freq; - /** Time interval mask for GCL entry */ - nveu32_t ti_mask; -}; - -/** - * @brief eqos_init_core_ops - Initialize EQOS core operations. - * - * @param[in] ops: Core operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void eqos_init_core_ops(struct core_ops *ops); - -/** - * @brief ivc_init_core_ops - Initialize IVC core operations. - * - * @param[in] ops: Core operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void ivc_init_core_ops(struct core_ops *ops); - -/** - * @brief mgbe_init_core_ops - Initialize MGBE core operations. - * - * @param[in] ops: Core operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void mgbe_init_core_ops(struct core_ops *ops); - -/** - * @brief ivc_init_macsec_ops - Initialize macsec core operations. - * - * @param[in] macsecops: Macsec operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void ivc_init_macsec_ops(void *macsecops); - -/** - * @brief hw_interface_init_core_ops - Initialize HW interface functions. - * - * @param[in] if_ops_p: interface core operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void hw_interface_init_core_ops(struct if_core_ops *if_ops_p); - -/** - * @brief ivc_interface_init_core_ops - Initialize IVC interface functions - * - * @param[in] if_ops_p: interface core operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p); - -/** - * @brief get osi pointer for PTP primary/sec interface - * - * @note - * Algorithm: - * - Returns OSI core data structure corresponding to mac-to-mac PTP - * role. - * - * @pre OSD layer should use this as first API to get osi_core pointer and - * use the same in remaning API invocation for mac-to-mac time sync. - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval valid and unique osi_core pointer on success - * @retval NULL on failure. - */ -struct osi_core_priv_data *get_role_pointer(nveu32_t role); -#endif /* INCLUDED_CORE_LOCAL_H */ diff --git a/osi/core/debug.c b/osi/core/debug.c deleted file mode 100644 index 8b16296..0000000 --- a/osi/core/debug.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2021, 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. - */ - -#ifdef OSI_DEBUG -#include "debug.h" - -/** - * @brief core_dump_struct - Dumps a given structure. - * - * @param[in] osi_core: OSI DMA private data structure. - * @param[in] ptr: Pointer to structure. - * @param[in] size: Size of structure to dump. - * - */ -static void core_dump_struct(struct osi_core_priv_data *osi_core, - unsigned char *ptr, - unsigned long size) -{ - nveu32_t i = 0, rem, j; - unsigned long temp; - - if (ptr == OSI_NULL) { - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "pointer is NULL\n"); - return; - } - - rem = i % 4; - temp = size - rem; - - for (i = 0; i < temp; i += 4) { - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "%02x%02x%02x%02x", ptr[i], ptr[i + 1], - ptr[i + 2], ptr[i + 3]); - j = i; - } - - for (i = j; i < size; i++) { - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, "%x", - ptr[i]); - } -} - -/** - * @brief core_structs_dump - Dumps OSI CORE structure. - * - * @param[in] osi_core: OSI CORE private data structure. - */ -void core_structs_dump(struct osi_core_priv_data *osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "CORE struct size = %lu", - sizeof(struct osi_core_priv_data)); - core_dump_struct(osi_core, (unsigned char *)osi_core, - sizeof(struct osi_core_priv_data)); -#ifdef MACSEC_SUPPORT - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "MACSEC ops size = %lu", - sizeof(struct osi_macsec_core_ops)); - core_dump_struct(osi_core, (unsigned char *)osi_core->macsec_ops, - sizeof(struct osi_macsec_core_ops)); - - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "MACSEC LUT status size = %lu", - sizeof(struct osi_macsec_lut_status)); - core_dump_struct(osi_core, (unsigned char *)osi_core->macsec_ops, - sizeof(struct osi_macsec_lut_status)); -#endif - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "HW features size = %lu", - sizeof(struct osi_hw_features)); - core_dump_struct(osi_core, (unsigned char *)osi_core->hw_feature, - sizeof(struct osi_hw_features)); - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "core local size = %lu", - sizeof(struct core_local)); - core_dump_struct(osi_core, (unsigned char *)l_core, - sizeof(struct core_local)); - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "core ops size = %lu", - sizeof(struct core_ops)); - core_dump_struct(osi_core, (unsigned char *)l_core->ops_p, - sizeof(struct core_ops)); - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_STRUCTS, - "if_ops_p struct size = %lu", - sizeof(struct if_core_ops)); - core_dump_struct(osi_core, (unsigned char *)l_core->if_ops_p, - sizeof(struct if_core_ops)); -} - -/** - * @brief reg_dump - Dumps MAC DMA registers - * - * @param[in] osi_core: OSI core private data structure. - */ -void core_reg_dump(struct osi_core_priv_data *osi_core) -{ - unsigned int max_addr; - unsigned int addr = 0x0; - unsigned int reg_val; - - switch (osi_core->mac_ver) { - case OSI_EQOS_MAC_5_00: - max_addr = 0x12E4; - break; - case OSI_EQOS_MAC_5_30: - max_addr = 0x14EC; - break; - case OSI_MGBE_MAC_3_10: - max_addr = 0x35FC; - break; - default: - return; - } - - while (1) { - if (addr > max_addr) - break; - - reg_val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + addr); - osi_core->osd_ops.printf(osi_core, OSI_DEBUG_TYPE_REG, - "%x: %x\n", addr, reg_val); - addr += 4; - } -} -#endif diff --git a/osi/core/debug.h b/osi/core/debug.h deleted file mode 100644 index 5029510..0000000 --- a/osi/core/debug.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021, 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 INCLUDED_CORE_DEBUG_H -#define INCLUDED_CORE_DEBUG_H - -#include -#include -#include "../osi/common/common.h" -#include "core_local.h" - -void core_reg_dump(struct osi_core_priv_data *osi_core); -void core_structs_dump(struct osi_core_priv_data *osi_core); - -#endif /* INCLUDED_CORE_DEBUG_H*/ diff --git a/osi/core/eqos_core.c b/osi/core/eqos_core.c deleted file mode 100644 index 4ab9a96..0000000 --- a/osi/core/eqos_core.c +++ /dev/null @@ -1,6936 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 "../osi/common/common.h" -#include -#include -#include "eqos_core.h" -#include "eqos_mmc.h" -#include "core_local.h" -#include "vlan_filter.h" -#include "core_common.h" - -#ifdef UPDATED_PAD_CAL -/* - * Forward declarations of local functions. - */ -static nve32_t eqos_post_pad_calibrate( - struct osi_core_priv_data *const osi_core); -static nve32_t eqos_pre_pad_calibrate( - struct osi_core_priv_data *const osi_core); -#endif /* UPDATED_PAD_CAL */ - -/** - * @brief eqos_core_safety_config - EQOS MAC core safety configuration - */ -static struct core_func_safety eqos_core_safety_config; - -/** - * @brief eqos_ptp_tsc_capture - read PTP and TSC registers - * - * Algorithm: - * - write 1 to ETHER_QOS_WRAP_SYNC_TSC_PTP_CAPTURE_0 - * - wait till ETHER_QOS_WRAP_SYNC_TSC_PTP_CAPTURE_0 is 0x0 - * - read and return following registers - * ETHER_QOS_WRAP_TSC_CAPTURE_LOW_0 - * ETHER_QOS_WRAP_TSC_CAPTURE_HIGH_0 - * ETHER_QOS_WRAP_PTP_CAPTURE_LOW_0 - * ETHER_QOS_WRAP_PTP_CAPTURE_HIGH_0 - * - * @param[in] base: EQOS virtual base address. - * @param[out]: osi_core_ptp_tsc_data register - * - * @note MAC needs to be out of reset and proper clock configured. TSC and PTP - * registers should be configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, - struct osi_core_ptp_tsc_data *data) -{ - nveu32_t retry = 20U; - nveu32_t count = 0U, val = 0U; - nve32_t cond = COND_NOT_MET; - nve32_t ret = -1; - - if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "ptp_tsc: older IP\n", 0ULL); - goto done; - } - osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)osi_core->base + - EQOS_WRAP_SYNC_TSC_PTP_CAPTURE); - - /* Poll Until Poll Condition */ - while (cond == COND_NOT_MET) { - if (count > retry) { - /* Max retries reached */ - goto done; - } - - count++; - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_SYNC_TSC_PTP_CAPTURE); - if ((val & OSI_ENABLE) == OSI_NONE) { - cond = COND_MET; - } else { - /* delay if SWR is set */ - osi_core->osd_ops.udelay(1U); - } - } - - data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_TSC_CAPTURE_LOW); - data->tsc_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_TSC_CAPTURE_HIGH); - data->ptp_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_PTP_CAPTURE_LOW); - data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_PTP_CAPTURE_HIGH); - ret = 0; -done: - return ret; -} - -/** - * @brief eqos_core_safety_writel - Write to safety critical register. - * - * @note - * Algorithm: - * - Acquire RW lock, so that eqos_validate_core_regs does not run while - * updating the safety critical register. - * - call osi_writela() to actually update the memory mapped register. - * - Store the same value in eqos_core_safety_config->reg_val[idx], - * so that this latest value will be compared when eqos_validate_core_regs - * is scheduled. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] addr: memory mapped register address to be written to. - * @param[in] idx: Index of register corresponding to enum func_safety_core_regs. - * - * @pre MAC has to be out of reset, and clocks supplied. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -static inline void eqos_core_safety_writel( - struct osi_core_priv_data *const osi_core, - nveu32_t val, void *addr, - nveu32_t idx) -{ - struct core_func_safety *config = &eqos_core_safety_config; - - osi_lock_irq_enabled(&config->core_safety_lock); - osi_writela(osi_core, val, addr); - config->reg_val[idx] = (val & config->reg_mask[idx]); - osi_unlock_irq_enabled(&config->core_safety_lock); -} - -/** - * @brief Initialize the eqos_core_safety_config. - * - * @note - * Algorithm: - * - Populate the list of safety critical registers and provide - * the address of the register - * - Register mask (to ignore reserved/self-critical bits in the reg). - * See eqos_validate_core_regs which can be invoked periodically to compare - * the last written value to this register vs the actual value read when - * eqos_validate_core_regs is scheduled. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_core_safety_init(struct osi_core_priv_data *const osi_core) -{ - struct core_func_safety *config = &eqos_core_safety_config; - nveu8_t *base = (nveu8_t *)osi_core->base; - nveu32_t val; - nveu32_t i, idx; - - /* Initialize all reg address to NULL, since we may not use - * some regs depending on the number of MTL queues enabled. - */ - for (i = EQOS_MAC_MCR_IDX; i < EQOS_MAX_CORE_SAFETY_REGS; i++) { - config->reg_addr[i] = OSI_NULL; - } - - /* Store reg addresses to run periodic read MAC registers.*/ - config->reg_addr[EQOS_MAC_MCR_IDX] = base + EQOS_MAC_MCR; - config->reg_addr[EQOS_MAC_PFR_IDX] = base + EQOS_MAC_PFR; - for (i = 0U; i < OSI_EQOS_MAX_HASH_REGS; i++) { - config->reg_addr[EQOS_MAC_HTR0_IDX + i] = - base + EQOS_MAC_HTR_REG(i); - } - config->reg_addr[EQOS_MAC_Q0_TXFC_IDX] = base + - EQOS_MAC_QX_TX_FLW_CTRL(0U); - config->reg_addr[EQOS_MAC_RQC0R_IDX] = base + EQOS_MAC_RQC0R; - config->reg_addr[EQOS_MAC_RQC1R_IDX] = base + EQOS_MAC_RQC1R; - config->reg_addr[EQOS_MAC_RQC2R_IDX] = base + EQOS_MAC_RQC2R; - config->reg_addr[EQOS_MAC_IMR_IDX] = base + EQOS_MAC_IMR; - config->reg_addr[EQOS_MAC_MA0HR_IDX] = base + EQOS_MAC_MA0HR; - config->reg_addr[EQOS_MAC_MA0LR_IDX] = base + EQOS_MAC_MA0LR; - config->reg_addr[EQOS_MAC_TCR_IDX] = base + EQOS_MAC_TCR; - config->reg_addr[EQOS_MAC_SSIR_IDX] = base + EQOS_MAC_SSIR; - config->reg_addr[EQOS_MAC_TAR_IDX] = base + EQOS_MAC_TAR; - config->reg_addr[EQOS_PAD_AUTO_CAL_CFG_IDX] = base + - EQOS_PAD_AUTO_CAL_CFG; - /* MTL registers */ - config->reg_addr[EQOS_MTL_RXQ_DMA_MAP0_IDX] = base + - EQOS_MTL_RXQ_DMA_MAP0; - for (i = 0U; i < osi_core->num_mtl_queues; i++) { - idx = osi_core->mtl_queues[i]; - if (idx >= OSI_EQOS_MAX_NUM_CHANS) { - continue; - } - - config->reg_addr[EQOS_MTL_CH0_TX_OP_MODE_IDX + idx] = base + - EQOS_MTL_CHX_TX_OP_MODE(idx); - config->reg_addr[EQOS_MTL_TXQ0_QW_IDX + idx] = base + - EQOS_MTL_TXQ_QW(idx); - config->reg_addr[EQOS_MTL_CH0_RX_OP_MODE_IDX + idx] = base + - EQOS_MTL_CHX_RX_OP_MODE(idx); - } - /* DMA registers */ - config->reg_addr[EQOS_DMA_SBUS_IDX] = base + EQOS_DMA_SBUS; - - /* Update the register mask to ignore reserved bits/self-clearing bits. - * MAC registers */ - config->reg_mask[EQOS_MAC_MCR_IDX] = EQOS_MAC_MCR_MASK; - config->reg_mask[EQOS_MAC_PFR_IDX] = EQOS_MAC_PFR_MASK; - for (i = 0U; i < OSI_EQOS_MAX_HASH_REGS; i++) { - config->reg_mask[EQOS_MAC_HTR0_IDX + i] = EQOS_MAC_HTR_MASK; - } - config->reg_mask[EQOS_MAC_Q0_TXFC_IDX] = EQOS_MAC_QX_TXFC_MASK; - config->reg_mask[EQOS_MAC_RQC0R_IDX] = EQOS_MAC_RQC0R_MASK; - config->reg_mask[EQOS_MAC_RQC1R_IDX] = EQOS_MAC_RQC1R_MASK; - config->reg_mask[EQOS_MAC_RQC2R_IDX] = EQOS_MAC_RQC2R_MASK; - config->reg_mask[EQOS_MAC_IMR_IDX] = EQOS_MAC_IMR_MASK; - config->reg_mask[EQOS_MAC_MA0HR_IDX] = EQOS_MAC_MA0HR_MASK; - config->reg_mask[EQOS_MAC_MA0LR_IDX] = EQOS_MAC_MA0LR_MASK; - config->reg_mask[EQOS_MAC_TCR_IDX] = EQOS_MAC_TCR_MASK; - config->reg_mask[EQOS_MAC_SSIR_IDX] = EQOS_MAC_SSIR_MASK; - config->reg_mask[EQOS_MAC_TAR_IDX] = EQOS_MAC_TAR_MASK; - config->reg_mask[EQOS_PAD_AUTO_CAL_CFG_IDX] = - EQOS_PAD_AUTO_CAL_CFG_MASK; - /* MTL registers */ - config->reg_mask[EQOS_MTL_RXQ_DMA_MAP0_IDX] = EQOS_RXQ_DMA_MAP0_MASK; - for (i = 0U; i < osi_core->num_mtl_queues; i++) { - idx = osi_core->mtl_queues[i]; - if (idx >= OSI_EQOS_MAX_NUM_CHANS) { - continue; - } - - config->reg_mask[EQOS_MTL_CH0_TX_OP_MODE_IDX + idx] = - EQOS_MTL_TXQ_OP_MODE_MASK; - config->reg_mask[EQOS_MTL_TXQ0_QW_IDX + idx] = - EQOS_MTL_TXQ_QW_MASK; - config->reg_mask[EQOS_MTL_CH0_RX_OP_MODE_IDX + idx] = - EQOS_MTL_RXQ_OP_MODE_MASK; - } - /* DMA registers */ - config->reg_mask[EQOS_DMA_SBUS_IDX] = EQOS_DMA_SBUS_MASK; - - /* Initialize current power-on-reset values of these registers */ - for (i = EQOS_MAC_MCR_IDX; i < EQOS_MAX_CORE_SAFETY_REGS; i++) { - if (config->reg_addr[i] == OSI_NULL) { - continue; - } - - val = osi_readla(osi_core, - (nveu8_t *)config->reg_addr[i]); - config->reg_val[i] = val & config->reg_mask[i]; - } - - osi_lock_init(&config->core_safety_lock); -} - -/** - * @brief Initialize the OSI core private data backup config array - * - * @note - * Algorithm: - * - Populate the list of core registers to be saved during suspend. - * Fill the address of each register in structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @param[in] osi_core: OSI core private data structure. - */ -static void eqos_core_backup_init(struct osi_core_priv_data *const osi_core) -{ - struct core_backup *config = &osi_core->backup_config; - nveu8_t *base = (nveu8_t *)osi_core->base; - nveu32_t i; - - /* MAC registers backup */ - config->reg_addr[EQOS_MAC_MCR_BAK_IDX] = base + EQOS_MAC_MCR; - config->reg_addr[EQOS_MAC_EXTR_BAK_IDX] = base + EQOS_MAC_EXTR; - config->reg_addr[EQOS_MAC_PFR_BAK_IDX] = base + EQOS_MAC_PFR; - config->reg_addr[EQOS_MAC_VLAN_TAG_BAK_IDX] = base + - EQOS_MAC_VLAN_TAG; - config->reg_addr[EQOS_MAC_VLANTIR_BAK_IDX] = base + EQOS_MAC_VLANTIR; - config->reg_addr[EQOS_MAC_RX_FLW_CTRL_BAK_IDX] = base + - EQOS_MAC_RX_FLW_CTRL; - config->reg_addr[EQOS_MAC_RQC0R_BAK_IDX] = base + EQOS_MAC_RQC0R; - config->reg_addr[EQOS_MAC_RQC1R_BAK_IDX] = base + EQOS_MAC_RQC1R; - config->reg_addr[EQOS_MAC_RQC2R_BAK_IDX] = base + EQOS_MAC_RQC2R; - config->reg_addr[EQOS_MAC_ISR_BAK_IDX] = base + EQOS_MAC_ISR; - config->reg_addr[EQOS_MAC_IMR_BAK_IDX] = base + EQOS_MAC_IMR; - config->reg_addr[EQOS_MAC_PMTCSR_BAK_IDX] = base + EQOS_MAC_PMTCSR; - config->reg_addr[EQOS_MAC_LPI_CSR_BAK_IDX] = base + EQOS_MAC_LPI_CSR; - config->reg_addr[EQOS_MAC_LPI_TIMER_CTRL_BAK_IDX] = base + - EQOS_MAC_LPI_TIMER_CTRL; - config->reg_addr[EQOS_MAC_LPI_EN_TIMER_BAK_IDX] = base + - EQOS_MAC_LPI_EN_TIMER; - config->reg_addr[EQOS_MAC_ANS_BAK_IDX] = base + EQOS_MAC_ANS; - config->reg_addr[EQOS_MAC_PCS_BAK_IDX] = base + EQOS_MAC_PCS; - if (osi_core->mac_ver == OSI_EQOS_MAC_5_00) { - config->reg_addr[EQOS_5_00_MAC_ARPPA_BAK_IDX] = base + - EQOS_5_00_MAC_ARPPA; - } - config->reg_addr[EQOS_MMC_CNTRL_BAK_IDX] = base + EQOS_MMC_CNTRL; - if (osi_core->mac_ver == OSI_EQOS_MAC_4_10) { - config->reg_addr[EQOS_4_10_MAC_ARPPA_BAK_IDX] = base + - EQOS_4_10_MAC_ARPPA; - } - config->reg_addr[EQOS_MAC_TCR_BAK_IDX] = base + EQOS_MAC_TCR; - config->reg_addr[EQOS_MAC_SSIR_BAK_IDX] = base + EQOS_MAC_SSIR; - config->reg_addr[EQOS_MAC_STSR_BAK_IDX] = base + EQOS_MAC_STSR; - config->reg_addr[EQOS_MAC_STNSR_BAK_IDX] = base + EQOS_MAC_STNSR; - config->reg_addr[EQOS_MAC_STSUR_BAK_IDX] = base + EQOS_MAC_STSUR; - config->reg_addr[EQOS_MAC_STNSUR_BAK_IDX] = base + EQOS_MAC_STNSUR; - config->reg_addr[EQOS_MAC_TAR_BAK_IDX] = base + EQOS_MAC_TAR; - config->reg_addr[EQOS_DMA_BMR_BAK_IDX] = base + EQOS_DMA_BMR; - config->reg_addr[EQOS_DMA_SBUS_BAK_IDX] = base + EQOS_DMA_SBUS; - config->reg_addr[EQOS_DMA_ISR_BAK_IDX] = base + EQOS_DMA_ISR; - config->reg_addr[EQOS_MTL_OP_MODE_BAK_IDX] = base + EQOS_MTL_OP_MODE; - config->reg_addr[EQOS_MTL_RXQ_DMA_MAP0_BAK_IDX] = base + - EQOS_MTL_RXQ_DMA_MAP0; - - for (i = 0; i < EQOS_MAX_HTR_REGS; i++) { - config->reg_addr[EQOS_MAC_HTR_REG_BAK_IDX(i)] = base + - EQOS_MAC_HTR_REG(i); - } - for (i = 0; i < OSI_EQOS_MAX_NUM_QUEUES; i++) { - config->reg_addr[EQOS_MAC_QX_TX_FLW_CTRL_BAK_IDX(i)] = base + - EQOS_MAC_QX_TX_FLW_CTRL(i); - } - for (i = 0; i < EQOS_MAX_MAC_ADDRESS_FILTER; i++) { - config->reg_addr[EQOS_MAC_ADDRH_BAK_IDX(i)] = base + - EQOS_MAC_ADDRH(i); - config->reg_addr[EQOS_MAC_ADDRL_BAK_IDX(i)] = base + - EQOS_MAC_ADDRL(i); - } - for (i = 0; i < EQOS_MAX_L3_L4_FILTER; i++) { - config->reg_addr[EQOS_MAC_L3L4_CTR_BAK_IDX(i)] = base + - EQOS_MAC_L3L4_CTR(i); - config->reg_addr[EQOS_MAC_L4_ADR_BAK_IDX(i)] = base + - EQOS_MAC_L4_ADR(i); - config->reg_addr[EQOS_MAC_L3_AD0R_BAK_IDX(i)] = base + - EQOS_MAC_L3_AD0R(i); - config->reg_addr[EQOS_MAC_L3_AD1R_BAK_IDX(i)] = base + - EQOS_MAC_L3_AD1R(i); - config->reg_addr[EQOS_MAC_L3_AD2R_BAK_IDX(i)] = base + - EQOS_MAC_L3_AD2R(i); - config->reg_addr[EQOS_MAC_L3_AD3R_BAK_IDX(i)] = base + - EQOS_MAC_L3_AD3R(i); - } - for (i = 0; i < OSI_EQOS_MAX_NUM_QUEUES; i++) { - config->reg_addr[EQOS_MTL_CHX_TX_OP_MODE_BAK_IDX(i)] = base + - EQOS_MTL_CHX_TX_OP_MODE(i); - config->reg_addr[EQOS_MTL_TXQ_ETS_CR_BAK_IDX(i)] = base + - EQOS_MTL_TXQ_ETS_CR(i); - config->reg_addr[EQOS_MTL_TXQ_QW_BAK_IDX(i)] = base + - EQOS_MTL_TXQ_QW(i); - config->reg_addr[EQOS_MTL_TXQ_ETS_SSCR_BAK_IDX(i)] = base + - EQOS_MTL_TXQ_ETS_SSCR(i); - config->reg_addr[EQOS_MTL_TXQ_ETS_HCR_BAK_IDX(i)] = base + - EQOS_MTL_TXQ_ETS_HCR(i); - config->reg_addr[EQOS_MTL_TXQ_ETS_LCR_BAK_IDX(i)] = base + - EQOS_MTL_TXQ_ETS_LCR(i); - config->reg_addr[EQOS_MTL_CHX_RX_OP_MODE_BAK_IDX(i)] = base + - EQOS_MTL_CHX_RX_OP_MODE(i); - } - - /* Wrapper register backup */ - config->reg_addr[EQOS_CLOCK_CTRL_0_BAK_IDX] = base + - EQOS_CLOCK_CTRL_0; - config->reg_addr[EQOS_AXI_ASID_CTRL_BAK_IDX] = base + - EQOS_AXI_ASID_CTRL; - config->reg_addr[EQOS_PAD_CRTL_BAK_IDX] = base + EQOS_PAD_CRTL; - config->reg_addr[EQOS_PAD_AUTO_CAL_CFG_BAK_IDX] = base + - EQOS_PAD_AUTO_CAL_CFG; -} - -/** - * @brief eqos_config_flow_control - Configure MAC flow control settings - * - * @note - * Algorithm: - * - Validate flw_ctrl for validity and return -1 if fails. - * - Configure Tx and(or) Rx flow control registers based on flw_ctrl. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: flw_ctrl settings. - * - If OSI_FLOW_CTRL_TX set, enable TX flow control, else disable. - * - If OSI_FLOW_CTRL_RX set, enable RX flow control, else disable. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_flow_control( - struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) -{ - nveu32_t val; - void *addr = osi_core->base; - - /* return on invalid argument */ - if (flw_ctrl > (OSI_FLOW_CTRL_RX | OSI_FLOW_CTRL_TX)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "flw_ctr: invalid input\n", 0ULL); - return -1; - } - - /* Configure MAC Tx Flow control */ - /* Read MAC Tx Flow control Register of Q0 */ - val = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_MAC_QX_TX_FLW_CTRL(0U)); - - /* flw_ctrl BIT0: 1 is for tx flow ctrl enable - * flw_ctrl BIT0: 0 is for tx flow ctrl disable - */ - if ((flw_ctrl & OSI_FLOW_CTRL_TX) == OSI_FLOW_CTRL_TX) { - /* Enable Tx Flow Control */ - val |= EQOS_MAC_QX_TX_FLW_CTRL_TFE; - /* Mask and set Pause Time */ - val &= ~EQOS_MAC_PAUSE_TIME_MASK; - val |= EQOS_MAC_PAUSE_TIME & EQOS_MAC_PAUSE_TIME_MASK; - } else { - /* Disable Tx Flow Control */ - val &= ~EQOS_MAC_QX_TX_FLW_CTRL_TFE; - } - - /* Write to MAC Tx Flow control Register of Q0 */ - eqos_core_safety_writel(osi_core, val, (nveu8_t *)addr + - EQOS_MAC_QX_TX_FLW_CTRL(0U), - EQOS_MAC_Q0_TXFC_IDX); - - /* Configure MAC Rx Flow control*/ - /* Read MAC Rx Flow control Register */ - val = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); - - /* flw_ctrl BIT1: 1 is for rx flow ctrl enable - * flw_ctrl BIT1: 0 is for rx flow ctrl disable - */ - if ((flw_ctrl & OSI_FLOW_CTRL_RX) == OSI_FLOW_CTRL_RX) { - /* Enable Rx Flow Control */ - val |= EQOS_MAC_RX_FLW_CTRL_RFE; - } else { - /* Disable Rx Flow Control */ - val &= ~EQOS_MAC_RX_FLW_CTRL_RFE; - } - - /* Write to MAC Rx Flow control Register */ - osi_writela(osi_core, val, - (nveu8_t *)addr + EQOS_MAC_RX_FLW_CTRL); - - return 0; -} - -/** - * @brief eqos_config_fw_err_pkts - Configure forwarding of error packets - * - * @note - * Algorithm: - * - Validate fw_err and return -1 if fails. - * - Enable or disable forward error packet confiration based on fw_err. - * - Refer to EQOS column of <> for API details. - * - TraceID: ETHERNET_NVETHERNETRM_020 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] qinx: Queue index. Max value OSI_EQOS_MAX_NUM_CHANS-1. - * @param[in] fw_err: Enable(OSI_ENABLE) or Disable(OSI_DISABLE) the forwarding of error packets - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_fw_err_pkts( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, - const nveu32_t fw_err) -{ - void *addr = osi_core->base; - nveu32_t val; - - /* Check for valid fw_err and qinx values */ - if (((fw_err != OSI_ENABLE) && (fw_err != OSI_DISABLE)) || - (qinx >= OSI_EQOS_MAX_NUM_CHANS)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "config_fw_err: invalid input\n", 0ULL); - return -1; - } - - /* Read MTL RXQ Operation_Mode Register */ - val = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_MTL_CHX_RX_OP_MODE(qinx)); - - /* fw_err, 1 is for enable and 0 is for disable */ - if (fw_err == OSI_ENABLE) { - /* When fw_err bit is set, all packets except the runt error - * packets are forwarded to the application or DMA. - */ - val |= EQOS_MTL_RXQ_OP_MODE_FEP; - } else if (fw_err == OSI_DISABLE) { - /* When this bit is reset, the Rx queue drops packets with error - * status (CRC error, GMII_ER, watchdog timeout, or overflow) - */ - val &= ~EQOS_MTL_RXQ_OP_MODE_FEP; - } else { - /* Nothing here */ - } - - /* Write to FEP bit of MTL RXQ operation Mode Register to enable or - * disable the forwarding of error packets to DMA or application. - */ - eqos_core_safety_writel(osi_core, val, (nveu8_t *)addr + - EQOS_MTL_CHX_RX_OP_MODE(qinx), - EQOS_MTL_CH0_RX_OP_MODE_IDX + qinx); - - return 0; -} - -/** - * @brief eqos_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) - * - * @note - * Algorithm: - * - Waits for SWR reset to be cleared in DMA Mode register for max polling count of 1000. - * - Sleeps for 1 milli sec for each iteration. - * - Refer to EQOS column of <> for API details. - * - TraceID: ETHERNET_NVETHERNETRM_004 - * - * @param[in] osi_core: OSI core private data structure.Used param base, osd_ops.usleep_range. - * - * @pre MAC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success if reset is success - * @retval -1 on if reset didnot happen in timeout. - */ -static nve32_t eqos_poll_for_swr(struct osi_core_priv_data *const osi_core) -{ - void *addr = osi_core->base; - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nveu32_t dma_bmr = 0; - nve32_t cond = COND_NOT_MET; - nveu32_t pre_si = osi_core->pre_si; - - if (pre_si == OSI_ENABLE) { - osi_writela(osi_core, OSI_ENABLE, - (nveu8_t *)addr + EQOS_DMA_BMR); - } - /* add delay of 10 usec */ - osi_core->osd_ops.usleep_range(9, 11); - - /* Poll Until Poll Condition */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_swr: timeout\n", 0ULL); - return -1; - } - - count++; - - - dma_bmr = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_DMA_BMR); - if ((dma_bmr & EQOS_DMA_BMR_SWR) != EQOS_DMA_BMR_SWR) { - cond = COND_MET; - } else { - osi_core->osd_ops.msleep(1U); - } - } - - return 0; -} - -/** - * @brief eqos_set_speed - Set operating speed - * - * @note - * Algorithm: - * - Based on the speed (10/100/1000Mbps) MAC will be configured - * accordingly. - * - If invalid value for speed, configure for 1000Mbps. - * - Refer to EQOS column of <> for API details. - * - TraceID: ETHERNET_NVETHERNETRM_012 - * - * @param[in] base: EQOS virtual base address. - * @param[in] speed: Operating speed. Valid values are OSI_SPEED_* - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @pre MAC should be initialized and started. see osi_start_mac() - */ -static int eqos_set_speed(struct osi_core_priv_data *const osi_core, - const nve32_t speed) -{ - nveu32_t mcr_val; - void *base = osi_core->base; - - mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); - switch (speed) { - default: - mcr_val &= ~EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - case OSI_SPEED_1000: - mcr_val &= ~EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - case OSI_SPEED_100: - mcr_val |= EQOS_MCR_PS; - mcr_val |= EQOS_MCR_FES; - break; - case OSI_SPEED_10: - mcr_val |= EQOS_MCR_PS; - mcr_val &= ~EQOS_MCR_FES; - break; - } - - eqos_core_safety_writel(osi_core, mcr_val, - (unsigned char *)osi_core->base + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - return 0; -} - -/** - * @brief eqos_set_mode - Set operating mode - * - * @note - * Algorithm: - * - Based on the mode (HALF/FULL Duplex) MAC will be configured - * accordingly. - * - If invalid value for mode, return -1. - * - Refer to EQOS column of <> for API details. - * - TraceID: ETHERNET_NVETHERNETRM_011 - * - * @param[in] osi_core: OSI core private data structure. used param is base. - * @param[in] mode: Operating mode. (OSI_FULL_DUPLEX/OSI_HALF_DUPLEX) - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_set_mode(struct osi_core_priv_data *const osi_core, - const nve32_t mode) -{ - void *base = osi_core->base; - nveu32_t mcr_val; - - mcr_val = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_MCR); - if (mode == OSI_FULL_DUPLEX) { - mcr_val |= EQOS_MCR_DM; - /* DO (disable receive own) bit is not applicable, don't care */ - mcr_val &= ~EQOS_MCR_DO; - } else if (mode == OSI_HALF_DUPLEX) { - mcr_val &= ~EQOS_MCR_DM; - /* Set DO (disable receive own) bit */ - mcr_val |= EQOS_MCR_DO; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "set_mode: invalid mode\n", 0ULL); - return -1; - /* Nothing here */ - } - eqos_core_safety_writel(osi_core, mcr_val, - (nveu8_t *)base + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - return 0; -} - -/** - * @brief eqos_calculate_per_queue_fifo - Calculate per queue FIFO size - * - * @note - * Algorithm: - * - Identify Total Tx/Rx HW FIFO size in KB based on fifo_size - * - Divide the same for each queue. - * - Correct the size to its nearest value of 256B to 32K with next correction value - * which is a 2power(2^x). - * - Correct for 9K and Max of 36K also. - * - i.e if share is >256 and < 512, set it to 256. - * - SWUD_ID: ETHERNET_NVETHERNETRM_006_1 - * - * @param[in] mac_ver: MAC version value. - * @param[in] fifo_size: Total Tx/RX HW FIFO size. - * @param[in] queue_count: Total number of Queues configured. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval Queue size that need to be programmed. - */ -static nveu32_t eqos_calculate_per_queue_fifo(nveu32_t mac_ver, - nveu32_t fifo_size, - nveu32_t queue_count) -{ - nveu32_t q_fifo_size = 0; /* calculated fifo size per queue */ - nveu32_t p_fifo = EQOS_256; /* per queue fifo size program value */ - - if (queue_count == 0U) { - return 0U; - } - - /* calculate Tx/Rx fifo share per queue */ - switch (fifo_size) { - case 0: - q_fifo_size = FIFO_SIZE_B(128U); - break; - case 1: - q_fifo_size = FIFO_SIZE_B(256U); - break; - case 2: - q_fifo_size = FIFO_SIZE_B(512U); - break; - case 3: - q_fifo_size = FIFO_SIZE_KB(1U); - break; - case 4: - q_fifo_size = FIFO_SIZE_KB(2U); - break; - case 5: - q_fifo_size = FIFO_SIZE_KB(4U); - break; - case 6: - q_fifo_size = FIFO_SIZE_KB(8U); - break; - case 7: - q_fifo_size = FIFO_SIZE_KB(16U); - break; - case 8: - q_fifo_size = FIFO_SIZE_KB(32U); - break; - case 9: - if (mac_ver == OSI_EQOS_MAC_5_30) { - q_fifo_size = FIFO_SIZE_KB(64U); - } else { - q_fifo_size = FIFO_SIZE_KB(36U); - } - break; - case 10: - q_fifo_size = FIFO_SIZE_KB(128U); - break; - case 11: - q_fifo_size = FIFO_SIZE_KB(256U); - break; - default: - q_fifo_size = FIFO_SIZE_KB(36U); - break; - } - - q_fifo_size = q_fifo_size / queue_count; - - if (q_fifo_size >= FIFO_SIZE_KB(36U)) { - p_fifo = EQOS_36K; - } else if (q_fifo_size >= FIFO_SIZE_KB(32U)) { - p_fifo = EQOS_32K; - } else if (q_fifo_size >= FIFO_SIZE_KB(16U)) { - p_fifo = EQOS_16K; - } else if (q_fifo_size == FIFO_SIZE_KB(9U)) { - p_fifo = EQOS_9K; - } else if (q_fifo_size >= FIFO_SIZE_KB(8U)) { - p_fifo = EQOS_8K; - } else if (q_fifo_size >= FIFO_SIZE_KB(4U)) { - p_fifo = EQOS_4K; - } else if (q_fifo_size >= FIFO_SIZE_KB(2U)) { - p_fifo = EQOS_2K; - } else if (q_fifo_size >= FIFO_SIZE_KB(1U)) { - p_fifo = EQOS_1K; - } else if (q_fifo_size >= FIFO_SIZE_B(512U)) { - p_fifo = EQOS_512; - } else if (q_fifo_size >= FIFO_SIZE_B(256U)) { - p_fifo = EQOS_256; - } else { - /* Nothing here */ - } - - return p_fifo; -} - -#ifdef UPDATED_PAD_CAL -/** - * @brief eqos_pad_calibrate - performs PAD calibration - * - * @note - * Algorithm: - * - Set field PAD_E_INPUT_OR_E_PWRD in reg ETHER_QOS_SDMEMCOMPPADCTRL_0 - * - Delay for 1 usec. - * - Set AUTO_CAL_ENABLE and AUTO_CAL_START in reg - * ETHER_QOS_AUTO_CAL_CONFIG_0 - * - Wait on AUTO_CAL_ACTIVE until it is 0 for a loop of 1000 with a sleep of 10 microsecond - * between itertions. - * - Re-program the value PAD_E_INPUT_OR_E_PWRD in - * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power - * - return 0 if wait for AUTO_CAL_ACTIVE is success else -1. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_013 - * - * @param[in] osi_core: OSI core private data structure. Used param is base, osd_ops.usleep_range. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) -{ - void *ioaddr = osi_core->base; - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nve32_t cond = COND_NOT_MET, ret = 0; - nveu32_t value; - - __sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, - OSI_DISABLE, OSI_ENABLE); - ret = eqos_pre_pad_calibrate(osi_core); - if (ret < 0) { - ret = -1; - goto error; - } - /* 1. Set field PAD_E_INPUT_OR_E_PWRD in - * reg ETHER_QOS_SDMEMCOMPPADCTRL_0 - */ - value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - value |= EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - - /* 2. delay for 1 to 3 usec */ - osi_core->osd_ops.usleep_range(1, 3); - - /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in - * reg ETHER_QOS_AUTO_CAL_CONFIG_0. - */ - value = osi_readla(osi_core, - (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); - value |= EQOS_PAD_AUTO_CAL_CFG_START | - EQOS_PAD_AUTO_CAL_CFG_ENABLE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)ioaddr + - EQOS_PAD_AUTO_CAL_CFG, - EQOS_PAD_AUTO_CAL_CFG_IDX); - - /* 4. Wait on 10 to 12 us before start checking for calibration done. - * This delay is consumed in delay inside while loop. - */ - - /* 5. Wait on AUTO_CAL_ACTIVE until it is 0. 10ms is the timeout */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - goto calibration_failed; - } - count++; - osi_core->osd_ops.usleep_range(10, 12); - value = osi_readla(osi_core, (nveu8_t *)ioaddr + - EQOS_PAD_AUTO_CAL_STAT); - /* calibration done when CAL_STAT_ACTIVE is zero */ - if ((value & EQOS_PAD_AUTO_CAL_STAT_ACTIVE) == 0U) { - cond = COND_MET; - } - } - -calibration_failed: - /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in - * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power - */ - value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - ret = eqos_post_pad_calibrate(osi_core) < 0 ? -1 : ret; -error: - __sync_val_compare_and_swap(&osi_core->padctrl.is_pad_cal_in_progress, - OSI_ENABLE, OSI_DISABLE); - - return ret; -} - -#else -/** - * @brief eqos_pad_calibrate - PAD calibration - * - * @note - * Algorithm: - * - Set field PAD_E_INPUT_OR_E_PWRD in reg ETHER_QOS_SDMEMCOMPPADCTRL_0 - * - Delay for 1 usec. - * - Set AUTO_CAL_ENABLE and AUTO_CAL_START in reg - * ETHER_QOS_AUTO_CAL_CONFIG_0 - * - Wait on AUTO_CAL_ACTIVE until it is 0 - * - Re-program the value PAD_E_INPUT_OR_E_PWRD in - * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * - MAC should out of reset and clocks enabled. - * - RGMII and MDIO interface needs to be IDLE before performing PAD - * calibration. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_pad_calibrate(struct osi_core_priv_data *const osi_core) -{ - void *ioaddr = osi_core->base; - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nve32_t cond = COND_NOT_MET, ret = 0; - nveu32_t value; - - /* 1. Set field PAD_E_INPUT_OR_E_PWRD in - * reg ETHER_QOS_SDMEMCOMPPADCTRL_0 - */ - value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - value |= EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - /* 2. delay for 1 usec */ - osi_core->osd_ops.usleep_range(1, 3); - /* 3. Set AUTO_CAL_ENABLE and AUTO_CAL_START in - * reg ETHER_QOS_AUTO_CAL_CONFIG_0. - */ - value = osi_readla(osi_core, - (nveu8_t *)ioaddr + EQOS_PAD_AUTO_CAL_CFG); - value |= EQOS_PAD_AUTO_CAL_CFG_START | - EQOS_PAD_AUTO_CAL_CFG_ENABLE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)ioaddr + - EQOS_PAD_AUTO_CAL_CFG, - EQOS_PAD_AUTO_CAL_CFG_IDX); - /* 4. Wait on 1 to 3 us before start checking for calibration done. - * This delay is consumed in delay inside while loop. - */ - /* 5. Wait on AUTO_CAL_ACTIVE until it is 0. 10ms is the timeout */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - ret = -1; - goto calibration_failed; - } - count++; - osi_core->osd_ops.usleep_range(10, 12); - value = osi_readla(osi_core, (nveu8_t *)ioaddr + - EQOS_PAD_AUTO_CAL_STAT); - /* calibration done when CAL_STAT_ACTIVE is zero */ - if ((value & EQOS_PAD_AUTO_CAL_STAT_ACTIVE) == 0U) { - cond = COND_MET; - } - } -calibration_failed: - /* 6. Re-program the value PAD_E_INPUT_OR_E_PWRD in - * ETHER_QOS_SDMEMCOMPPADCTRL_0 to save power - */ - value = osi_readla(osi_core, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - value &= ~EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD; - osi_writela(osi_core, value, (nveu8_t *)ioaddr + EQOS_PAD_CRTL); - return ret; -} -#endif /* UPDATED_PAD_CAL */ - -/** - * @brief eqos_flush_mtl_tx_queue - Flush MTL Tx queue - * - * @note - * Algorithm: - * - Validate qinx for maximum value of OSI_EQOS_MAX_NUM_QUEUES and return -1 if fails. - * - Configure EQOS_MTL_CHX_TX_OP_MODE to flush corresponding MTL queue. - * - Wait on EQOS_MTL_QTOMR_FTQ_LPOS bit set for a loop of 1000 with a sleep of - * 1 milli second between itertions. - * - return 0 if EQOS_MTL_QTOMR_FTQ_LPOS is set else -1. - * - SWUD_ID: ETHERNET_NVETHERNETRM_006_2 - * - * @param[in] osi_core: OSI core private data structure. Used param base, osd_ops.msleep. - * @param[in] qinx: MTL queue index. Max value is OSI_EQOS_MAX_NUM_QUEUES-1. - * - * @note - * - MAC should out of reset and clocks enabled. - * - hw core initialized. see osi_hw_core_init(). - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_flush_mtl_tx_queue( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) -{ - void *addr = osi_core->base; - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nveu32_t value; - nve32_t cond = COND_NOT_MET; - - if (qinx >= OSI_EQOS_MAX_NUM_QUEUES) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "flush_mtl_tx_queue: invalid input\n", 0ULL); - return -1; - } - - /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readla(osi_core, (nveu8_t *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); - value |= EQOS_MTL_QTOMR_FTQ; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx), - EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); - - /* Poll Until FTQ bit resets for Successful Tx Q flush */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Poll FTQ bit timeout\n", 0ULL); - return -1; - } - - count++; - osi_core->osd_ops.msleep(1); - - value = osi_readla(osi_core, (nveu8_t *)addr + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); - - if ((value & EQOS_MTL_QTOMR_FTQ_LPOS) == 0U) { - cond = COND_MET; - } - } - - return 0; -} - -/** - * @brief update_ehfc_rfa_rfd - Update EHFC, RFD and RSA values - * - * @note - * Algorithm: - * - Caculates and stores the RSD (Threshold for Deactivating - * Flow control) and RSA (Threshold for Activating Flow Control) values - * based on the Rx FIFO size and also enables HW flow control. - * - Maping detials for rx_fifo are:(minimum EQOS_4K) - * - EQOS_4K, configure FULL_MINUS_2_5K for RFD and FULL_MINUS_1_5K for RFA - * - EQOS_8K, configure FULL_MINUS_4_K for RFD and FULL_MINUS_6_K for RFA - * - EQOS_16K, configure FULL_MINUS_4_K for RFD and FULL_MINUS_10_K for RFA - * - EQOS_32K, configure FULL_MINUS_4_K for RFD and FULL_MINUS_16_K for RFA - * - EQOS_9K/Deafult, configure FULL_MINUS_3_K for RFD and FULL_MINUS_2_K for RFA - * - SWUD_ID: ETHERNET_NVETHERNETRM_006_3 - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @param[in] rx_fifo: Rx FIFO size. - * @param[out] value: Stores RFD and RSA values - */ -void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value) -{ - if (rx_fifo >= EQOS_4K) { - /* Enable HW Flow Control */ - *value |= EQOS_MTL_RXQ_OP_MODE_EHFC; - - switch (rx_fifo) { - case EQOS_4K: - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_2_5K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_1_5K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case EQOS_8K: - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_6_K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case EQOS_9K: - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_3_K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_2_K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case EQOS_16K: - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_10_K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case EQOS_32K: - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_16_K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - default: - /* Use 9K values */ - /* Update RFD */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_3_K << - EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_2_K << - EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT) & - EQOS_MTL_RXQ_OP_MODE_RFA_MASK; - break; - } - } -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief eqos_configure_mtl_queue - Configure MTL Queue - * - * @note - * Algorithm: - * - This takes care of configuring the below - * parameters for the MTL Queue - * - Mapping MTL Rx queue and DMA Rx channel - * - Flush TxQ - * - Enable Store and Forward mode for Tx, Rx - * - Configure Tx and Rx MTL Queue sizes - * - Configure TxQ weight - * - Enable Rx Queues - * - * @param[in] qinx: Queue number that need to be configured. - * @param[in] osi_core: OSI core private data. - * @param[in] tx_fifo: MTL TX queue size for a MTL queue. - * @param[in] rx_fifo: MTL RX queue size for a MTL queue. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_configure_mtl_queue(nveu32_t qinx, - struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo, - nveu32_t rx_fifo) -{ - nveu32_t value = 0; - nve32_t ret = 0; - - ret = eqos_flush_mtl_tx_queue(osi_core, qinx); - if (ret < 0) { - return ret; - } - - value = (tx_fifo << EQOS_MTL_TXQ_SIZE_SHIFT); - /* Enable Store and Forward mode */ - value |= EQOS_MTL_TSF; - /* Enable TxQ */ - value |= EQOS_MTL_TXQEN; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx), - EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); - - /* read RX Q0 Operating Mode Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_RX_OP_MODE(qinx)); - value |= (rx_fifo << EQOS_MTL_RXQ_SIZE_SHIFT); - /* Enable Store and Forward mode */ - value |= EQOS_MTL_RSF; - /* Update EHFL, RFA and RFD - * EHFL: Enable HW Flow Control - * RFA: Threshold for Activating Flow Control - * RFD: Threshold for Deactivating Flow Control - */ - update_ehfc_rfa_rfd(rx_fifo, &value); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_RX_OP_MODE(qinx), - EQOS_MTL_CH0_RX_OP_MODE_IDX + qinx); - - /* Transmit Queue weight */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); - value |= (EQOS_MTL_TXQ_QW_ISCQW + qinx); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx), - EQOS_MTL_TXQ0_QW_IDX + qinx); - - /* Enable Rx Queue Control */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC0R); - value |= ((osi_core->rxq_ctrl[qinx] & EQOS_RXQ_EN_MASK) << (qinx * 2U)); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC0R, EQOS_MAC_RQC0R_IDX); - - return 0; -} -/** \endcond */ - -/** - * @brief eqos_config_rxcsum_offload - Enable/Disable rx checksum offload in HW - * - * @note - * Algorithm: - * - VAlidate enabled param and return -1 if invalid. - * - Read the MAC configuration register. - * - Enable/disable the IP checksum offload engine COE in MAC receiver based on enabled. - * - Update the MAC configuration register. - * - Refer to OSI column of <> for sequence - * of execution. - * - TraceID:ETHERNET_NVETHERNETRM_017 - * - * @param[in] osi_core: OSI core private data structure. Used param is base. - * @param[in] enabled: Flag to indicate feature is to be enabled(OSI_ENABLE)/disabled(OSI_DISABLE). - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - const nveu32_t enabled) -{ - void *addr = osi_core->base; - nveu32_t mac_mcr; - - if ((enabled != OSI_ENABLE) && (enabled != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "rxsum_offload: invalid input\n", 0ULL); - return -1; - } - - mac_mcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - - if (enabled == OSI_ENABLE) { - mac_mcr |= EQOS_MCR_IPC; - } else { - mac_mcr &= ~EQOS_MCR_IPC; - } - - eqos_core_safety_writel(osi_core, mac_mcr, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - - return 0; -} - -/** - * @brief eqos_config_frp - Enable/Disale RX Flexible Receive Parser in HW - * - * Algorithm: - * 1) Read the MTL OP Mode configuration register. - * 2) Enable/Disable FRPE bit based on the input. - * 3) Write the MTL OP Mode configuration register. - * - * @param[in] osi_core: OSI core private data. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_frp(struct osi_core_priv_data *const osi_core, - const unsigned int enabled) -{ - unsigned char *base = osi_core->base; - unsigned int op_mode = 0U, val = 0U; - int ret = 0; - - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid enable input\n", - enabled); - return -1; - } - - /* Disable RE */ - val = osi_readl(base + EQOS_MAC_MCR); - val &= ~EQOS_MCR_RE; - osi_writel(val, base + EQOS_MAC_MCR); - - op_mode = osi_readl(base + EQOS_MTL_OP_MODE); - if (enabled == OSI_ENABLE) { - /* Set FRPE bit of MTL_Operation_Mode register */ - op_mode |= EQOS_MTL_OP_MODE_FRPE; - } else { - /* Reset FRPE bit of MTL_Operation_Mode register */ - op_mode &= ~EQOS_MTL_OP_MODE_FRPE; - } - osi_writel(op_mode, base + EQOS_MTL_OP_MODE); - - /* Verify RXPI bit set in MTL_RXP_Control_Status */ - ret = osi_readl_poll_timeout((base + EQOS_MTL_RXP_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & EQOS_MTL_RXP_CS_RXPI) == - EQOS_MTL_RXP_CS_RXPI), - (EQOS_MTL_FRP_READ_UDELAY), - (EQOS_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to enable FRP\n", - val); - goto frp_enable_re; - } - - val = osi_readl(base + EQOS_MTL_RXP_INTR_CS); - if (enabled == OSI_ENABLE) { - /* Enable FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - val |= (EQOS_MTL_RXP_INTR_CS_NVEOVIE | - EQOS_MTL_RXP_INTR_CS_NPEOVIE | - EQOS_MTL_RXP_INTR_CS_FOOVIE | - EQOS_MTL_RXP_INTR_CS_PDRFIE); - } else { - /* Disable FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - val &= ~(EQOS_MTL_RXP_INTR_CS_NVEOVIE | - EQOS_MTL_RXP_INTR_CS_NPEOVIE | - EQOS_MTL_RXP_INTR_CS_FOOVIE | - EQOS_MTL_RXP_INTR_CS_PDRFIE); - } - osi_writel(val, base + EQOS_MTL_RXP_INTR_CS); - -frp_enable_re: - /* Enable RE */ - val = osi_readla(osi_core, base + EQOS_MAC_MCR); - val |= EQOS_MCR_RE; - osi_writela(osi_core, val, base + EQOS_MAC_MCR); - - return ret; -} - -/** - * @brief eqos_update_frp_nve - Update FRP NVE into HW - * - * Algorithm: - * - * @param[in] osi_core: OSI core private data. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_update_frp_nve(struct osi_core_priv_data *const osi_core, - const unsigned int nve) -{ - unsigned int val; - unsigned char *base = osi_core->base; - - /* Validate the NVE value */ - if (nve >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid NVE value\n", - nve); - return -1; - } - - /* Update NVE and NPE in MTL_RXP_Control_Status register */ - val = osi_readla(osi_core, base + EQOS_MTL_RXP_CS); - /* Clear old NVE and NPE */ - val &= ~(EQOS_MTL_RXP_CS_NVE | EQOS_MTL_RXP_CS_NPE); - /* Add new NVE and NVE */ - val |= (nve & EQOS_MTL_RXP_CS_NVE); - val |= ((nve << EQOS_MTL_RXP_CS_NPE_SHIFT) & EQOS_MTL_RXP_CS_NPE); - osi_writela(osi_core, val, base + EQOS_MTL_RXP_CS); - - return 0; -} - -/** - * @brief eqos_frp_write - Write FRP entry into HW - * - * Algorithm: This function will write FRP entry registers into HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] addr: FRP register address. - * @param[in] data: FRP register data. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_frp_write(struct osi_core_priv_data *osi_core, - unsigned int addr, - unsigned int data) -{ - int ret = 0; - unsigned char *base = osi_core->base; - unsigned int val = 0U; - - /* Wait for ready */ - ret = osi_readl_poll_timeout((base + EQOS_MTL_RXP_IND_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & EQOS_MTL_RXP_IND_CS_BUSY) == - OSI_NONE), - (EQOS_MTL_FRP_READ_UDELAY), - (EQOS_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to write\n", - val); - return -1; - } - - /* Write data into MTL_RXP_Indirect_Acc_Data */ - osi_writel(data, base + EQOS_MTL_RXP_IND_DATA); - - /* Program MTL_RXP_Indirect_Acc_Control_Status */ - val = osi_readl(base + EQOS_MTL_RXP_IND_CS); - /* Set WRRDN for write */ - val |= EQOS_MTL_RXP_IND_CS_WRRDN; - /* Clear and add ADDR */ - val &= ~EQOS_MTL_RXP_IND_CS_ADDR; - val |= (addr & EQOS_MTL_RXP_IND_CS_ADDR); - /* Start write */ - val |= EQOS_MTL_RXP_IND_CS_BUSY; - osi_writel(val, base + EQOS_MTL_RXP_IND_CS); - - /* Wait for complete */ - ret = osi_readl_poll_timeout((base + EQOS_MTL_RXP_IND_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & EQOS_MTL_RXP_IND_CS_BUSY) == - OSI_NONE), - (EQOS_MTL_FRP_READ_UDELAY), - (EQOS_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to write\n", - val); - return -1; - } - - return ret; -} - -/** - * @brief eqos_update_frp_entry - Update FRP Instruction Table entry in HW - * - * Algorithm: - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] pos: FRP Instruction Table entry location. - * @param[in] data: FRP entry data structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_update_frp_entry(struct osi_core_priv_data *const osi_core, - const unsigned int pos, - struct osi_core_frp_data *const data) -{ - unsigned int val = 0U, tmp = 0U; - int ret = -1; - - /* Validate pos value */ - if (pos >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid FRP table entry\n", - pos); - return -1; - } - - /** Write Match Data into IE0 **/ - val = data->match_data; - ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE0(pos), val); - if (ret < 0) { - /* Match Data Write fail */ - return -1; - } - - /** Write Match Enable into IE1 **/ - val = data->match_en; - ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE1(pos), val); - if (ret < 0) { - /* Match Enable Write fail */ - return -1; - } - - /** Write AF, RF, IM, NIC, FO and OKI into IE2 **/ - val = 0; - if (data->accept_frame == OSI_ENABLE) { - /* Set AF Bit */ - val |= EQOS_MTL_FRP_IE2_AF; - } - if (data->reject_frame == OSI_ENABLE) { - /* Set RF Bit */ - val |= EQOS_MTL_FRP_IE2_RF; - } - if (data->inverse_match == OSI_ENABLE) { - /* Set IM Bit */ - val |= EQOS_MTL_FRP_IE2_IM; - } - if (data->next_ins_ctrl == OSI_ENABLE) { - /* Set NIC Bit */ - val |= EQOS_MTL_FRP_IE2_NC; - } - tmp = data->frame_offset; - val |= ((tmp << EQOS_MTL_FRP_IE2_FO_SHIFT) & EQOS_MTL_FRP_IE2_FO); - tmp = data->ok_index; - val |= ((tmp << EQOS_MTL_FRP_IE2_OKI_SHIFT) & EQOS_MTL_FRP_IE2_OKI); - tmp = data->dma_chsel; - val |= ((tmp << EQOS_MTL_FRP_IE2_DCH_SHIFT) & EQOS_MTL_FRP_IE2_DCH); - ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE2(pos), val); - if (ret < 0) { - /* FRP IE2 Write fail */ - return -1; - } - - /** Write DCH into IE3 **/ - val = OSI_NONE; - ret = eqos_frp_write(osi_core, EQOS_MTL_FRP_IE3(pos), val); - if (ret < 0) { - /* DCH Write fail */ - return -1; - } - - return ret; -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief eqos_configure_rxq_priority - Configure Priorities Selected in - * the Receive Queue - * - * @note - * Algorithm: - * - This takes care of mapping user priority to Rx queue. - * User provided priority mask updated to register. Valid input can have - * all TC(0xFF) in one queue to None(0x00) in rx queue. - * The software must ensure that the content of this field is mutually - * exclusive to the PSRQ fields for other queues, that is, the same - * priority is not mapped to multiple Rx queues. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_configure_rxq_priority( - struct osi_core_priv_data *const osi_core) -{ - nveu32_t val; - nveu32_t temp; - nveu32_t qinx, mtlq; - nveu32_t pmask = 0x0U; - nveu32_t mfix_var1, mfix_var2; - - /* make sure EQOS_MAC_RQC2R is reset before programming */ - osi_writela(osi_core, OSI_DISABLE, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC2R); - - for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { - mtlq = osi_core->mtl_queues[qinx]; - /* check for PSRQ field mutual exclusive for all queues */ - if ((osi_core->rxq_prio[mtlq] <= 0xFFU) && - (osi_core->rxq_prio[mtlq] > 0x0U) && - ((pmask & osi_core->rxq_prio[mtlq]) == 0U)) { - pmask |= osi_core->rxq_prio[mtlq]; - temp = osi_core->rxq_prio[mtlq]; - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid rxq Priority for Q\n", - (nveul64_t)mtlq); - continue; - - } - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC2R); - mfix_var1 = mtlq * (nveu32_t)EQOS_MAC_RQC2_PSRQ_SHIFT; - mfix_var2 = (nveu32_t)EQOS_MAC_RQC2_PSRQ_MASK; - mfix_var2 <<= mfix_var1; - val &= ~mfix_var2; - temp = temp << (mtlq * EQOS_MAC_RQC2_PSRQ_SHIFT); - mfix_var1 = mtlq * (nveu32_t)EQOS_MAC_RQC2_PSRQ_SHIFT; - mfix_var2 = (nveu32_t)EQOS_MAC_RQC2_PSRQ_MASK; - mfix_var2 <<= mfix_var1; - val |= (temp & mfix_var2); - /* Priorities Selected in the Receive Queue 0 */ - eqos_core_safety_writel(osi_core, val, - (nveu8_t *)osi_core->base + - EQOS_MAC_RQC2R, EQOS_MAC_RQC2R_IDX); - } -} - -#ifdef HSI_SUPPORT -/** - * @brief eqos_hsi_configure - Configure HSI features - * - * @note - * Algorithm: - * - Enables LIC interrupt and configure HSI features - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] enable: OSI_ENABLE for enabling HSI feature, else disable - * - * @retval 0 on success - * @retval -1 on failure - */ -static int eqos_hsi_configure(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value; - - if (enable == OSI_ENABLE) { - osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_err_code[osi_core->instance_id][REPORTER_IDX]; - - /* T23X-EQOS_HSIv2-19: Enabling of Consistency Monitor for TX Frame Errors */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_IMR); - value |= EQOS_IMR_TXESIE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - - /* T23X-EQOS_HSIv2-1: Enabling of Memory ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_CONTROL); - value |= EQOS_MTL_ECC_MTXEE; - value |= EQOS_MTL_ECC_MRXEE; - value |= EQOS_MTL_ECC_MESTEE; - value |= EQOS_MTL_ECC_MRXPEE; - value |= EQOS_MTL_ECC_TSOEE; - value |= EQOS_MTL_ECC_DSCEE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_CONTROL); - - /* T23X-EQOS_HSIv2-5: Enabling and Initialization of Transaction Timeout */ - value = (0x198U << EQOS_TMR_SHIFT) & EQOS_TMR_MASK; - value |= (0x2U << EQOS_LTMRMD_SHIFT) & EQOS_LTMRMD_MASK; - value |= (0x1U << EQOS_NTMRMD_SHIFT) & EQOS_NTMRMD_MASK; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MAC_FSM_ACT_TIMER); - - /* T23X-EQOS_HSIv2-3: Enabling and Initialization of Watchdog */ - /* T23X-EQOS_HSIv2-4: Enabling of Consistency Monitor for FSM States */ - // TODO: enable EQOS_TMOUTEN - value = EQOS_PRTYEN; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MAC_FSM_CONTROL); - - /* T23X-EQOS_HSIv2-2: Enabling of Bus Parity */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_DPP_CONTROL); - value |= EQOS_EDPP; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MTL_DPP_CONTROL); - - /* Enable Interrupts */ - /* T23X-EQOS_HSIv2-1: Enabling of Memory ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_INTERRUPT_ENABLE); - value |= EQOS_MTL_TXCEIE; - value |= EQOS_MTL_RXCEIE; - value |= EQOS_MTL_ECEIE; - value |= EQOS_MTL_RPCEIE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_DMA_ECC_INTERRUPT_ENABLE); - value |= EQOS_DMA_TCEIE; - value |= EQOS_DMA_DCEIE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_DMA_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - value |= EQOS_REGISTER_PARITY_ERR; - value |= EQOS_CORE_CORRECTABLE_ERR; - value |= EQOS_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - } else { - osi_core->hsi.enabled = OSI_DISABLE; - - /* T23X-EQOS_HSIv2-19: Disable of Consistency Monitor for TX Frame Errors */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_IMR); - value &= ~EQOS_IMR_TXESIE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - - /* T23X-EQOS_HSIv2-1: Disable of Memory ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_CONTROL); - value &= ~EQOS_MTL_ECC_MTXEE; - value &= ~EQOS_MTL_ECC_MRXEE; - value &= ~EQOS_MTL_ECC_MESTEE; - value &= ~EQOS_MTL_ECC_MRXPEE; - value &= ~EQOS_MTL_ECC_TSOEE; - value &= ~EQOS_MTL_ECC_DSCEE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_CONTROL); - - /* T23X-EQOS_HSIv2-5: Denitialization of Transaction Timeout */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + EQOS_MAC_FSM_ACT_TIMER); - - /* T23X-EQOS_HSIv2-4: Disable of Consistency Monitor for FSM States */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + EQOS_MAC_FSM_CONTROL); - - /* T23X-EQOS_HSIv2-2: Disable of Bus Parity */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_DPP_CONTROL); - value &= ~EQOS_EDPP; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MTL_DPP_CONTROL); - - /* Disable Interrupts */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + EQOS_MTL_ECC_INTERRUPT_ENABLE); - - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + EQOS_DMA_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - value &= ~EQOS_REGISTER_PARITY_ERR; - value &= ~EQOS_CORE_CORRECTABLE_ERR; - value &= ~EQOS_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - } - return 0; -} -#endif -/** - * @brief eqos_configure_mac - Configure MAC - * - * @note - * Algorithm: - * - This takes care of configuring the below - * parameters for the MAC - * - Enable required MAC control fields in MCR - * - Enable JE/JD/WD/GPSLCE based on the MTU size - * - Enable Multicast and Broadcast Queue - * - Disable MMC interrupts and Configure the MMC counters - * - Enable required MAC interrupts - * - * @param[in, out] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_configure_mac(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - nveu32_t mac_ext; - - /* Read MAC Configuration Register */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_MCR); - /* Enable Automatic Pad or CRC Stripping */ - /* Enable CRC stripping for Type packets */ - /* Enable Full Duplex mode */ - /* Enable Rx checksum offload engine by default */ - value |= EQOS_MCR_ACS | EQOS_MCR_CST | EQOS_MCR_DM | EQOS_MCR_IPC; - - if ((osi_core->mtu > OSI_DFLT_MTU_SIZE) && - (osi_core->mtu <= OSI_MTU_SIZE_9000)) { - /* if MTU less than or equal to 9K use JE */ - value |= EQOS_MCR_JE; - value |= EQOS_MCR_JD; - } else if (osi_core->mtu > OSI_MTU_SIZE_9000) { - /* if MTU greater 9K use GPSLCE */ - value |= EQOS_MCR_JD | EQOS_MCR_WD; - value |= EQOS_MCR_GPSLCE; - /* Read MAC Extension Register */ - mac_ext = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - /* Configure GPSL */ - mac_ext &= ~EQOS_MAC_EXTR_GPSL_MSK; - mac_ext |= OSI_MAX_MTU_SIZE & EQOS_MAC_EXTR_GPSL_MSK; - /* Write MAC Extension Register */ - osi_writela(osi_core, mac_ext, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - } else { - /* do nothing for default mtu size */ - } - - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_MCR, EQOS_MAC_MCR_IDX); - - /* Enable common interrupt at wrapper level */ - if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - value |= EQOS_MAC_SBD_INTR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - } - - /* enable Packet Duplication Control */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_EXTR); - if (osi_core->mac_ver >= OSI_EQOS_MAC_5_00) { - value |= EQOS_MAC_EXTR_PDC; - } - /* Write to MAC Extension Register */ - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + EQOS_MAC_EXTR); - - /* Enable Multicast and Broadcast Queue, default is Q0 */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_RQC1R); - value |= EQOS_MAC_RQC1R_MCBCQEN; - - /* Routing Multicast and Broadcast depending on mac version */ - value &= ~(EQOS_MAC_RQC1R_MCBCQ); - if (osi_core->mac_ver > OSI_EQOS_MAC_5_00) { - value |= EQOS_MAC_RQC1R_MCBCQ7 << EQOS_MAC_RQC1R_MCBCQ_SHIFT; - } else { - value |= EQOS_MAC_RQC1R_MCBCQ3 << EQOS_MAC_RQC1R_MCBCQ_SHIFT; - } - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_RQC1R, EQOS_MAC_RQC1R_IDX); - - /* Disable all MMC interrupts */ - /* Disable all MMC Tx Interrupts */ - osi_writela(osi_core, EQOS_MMC_INTR_DISABLE, (nveu8_t *)osi_core->base + - EQOS_MMC_TX_INTR_MASK); - /* Disable all MMC RX interrupts */ - osi_writela(osi_core, EQOS_MMC_INTR_DISABLE, (nveu8_t *)osi_core->base + - EQOS_MMC_RX_INTR_MASK); - /* Disable MMC Rx interrupts for IPC */ - osi_writela(osi_core, EQOS_MMC_INTR_DISABLE, (nveu8_t *)osi_core->base + - EQOS_MMC_IPC_RX_INTR_MASK); - - /* Configure MMC counters */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - value |= EQOS_MMC_CNTRL_CNTRST | EQOS_MMC_CNTRL_RSTONRD | - EQOS_MMC_CNTRL_CNTPRST | EQOS_MMC_CNTRL_CNTPRSTLVL; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - - /* Enable MAC interrupts */ - /* Read MAC IMR Register */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_IMR); - /* RGSMIIIE - RGMII/SMII interrupt Enable. - * LPIIE is not enabled. MMC LPI counters is maintained in HW */ - value |= EQOS_IMR_RGSMIIIE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - - /* Enable VLAN configuration */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); - /* Enable VLAN Tag stripping always - * Enable operation on the outer VLAN Tag, if present - * Disable double VLAN Tag processing on TX and RX - * Enable VLAN Tag in RX Status - * Disable VLAN Type Check - */ - if (osi_core->strip_vlan_tag == OSI_ENABLE) { - value |= EQOS_MAC_VLANTR_EVLS_ALWAYS_STRIP; - } - value |= EQOS_MAC_VLANTR_EVLRXS | EQOS_MAC_VLANTR_DOVLTC; - value &= ~EQOS_MAC_VLANTR_ERIVLT; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MAC_VLAN_TAG); - - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); - /* Enable VLAN tagging through context descriptor */ - value |= EQOS_MAC_VLANTIR_VLTI; - /* insert/replace C_VLAN in 13th & 14th bytes of transmitted frames */ - value &= ~EQOS_MAC_VLANTIRR_CSVL; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MAC_VLANTIR); - - /* Configure default flow control settings */ - if (osi_core->pause_frames != OSI_PAUSE_FRAMES_DISABLE) { - osi_core->flow_ctrl = (OSI_FLOW_CTRL_TX | OSI_FLOW_CTRL_RX); - if (eqos_config_flow_control(osi_core, - osi_core->flow_ctrl) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set flow control configuration\n", - 0ULL); - } - } - /* USP (user Priority) to RxQ Mapping, only if DCS not enabled */ - if (osi_core->dcs_en != OSI_ENABLE) { - eqos_configure_rxq_priority(osi_core); - } -} -/** - * @brief eqos_configure_dma - Configure DMA - * - * @note - * Algorithm: - * - This takes care of configuring the below - * parameters for the DMA - * - Programming different burst length for the DMA - * - Enable enhanced Address mode - * - Programming max read outstanding request limit - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_configure_dma(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value = 0; - void *base = osi_core->base; - - /* AXI Burst Length 8*/ - value |= EQOS_DMA_SBUS_BLEN8; - /* AXI Burst Length 16*/ - value |= EQOS_DMA_SBUS_BLEN16; - /* Enhanced Address Mode Enable */ - value |= EQOS_DMA_SBUS_EAME; - /* AXI Maximum Read Outstanding Request Limit = 31 */ - value |= EQOS_DMA_SBUS_RD_OSR_LMT; - /* AXI Maximum Write Outstanding Request Limit = 31 */ - value |= EQOS_DMA_SBUS_WR_OSR_LMT; - - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)base + EQOS_DMA_SBUS, - EQOS_DMA_SBUS_IDX); - - value = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_BMR); - value |= EQOS_DMA_BMR_DPSW; - osi_writela(osi_core, value, (nveu8_t *)base + EQOS_DMA_BMR); -} -/** \endcond */ - -/** - * @brief eqos_enable_mtl_interrupts - Enable MTL interrupts - * - * Algorithm: enable MTL interrupts for EST - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void eqos_enable_mtl_interrupts( - struct osi_core_priv_data *const osi_core) -{ - unsigned int mtl_est_ir = OSI_DISABLE; - void *addr = osi_core->base; - - mtl_est_ir = osi_readla(osi_core, (unsigned char *) - addr + EQOS_MTL_EST_ITRE); - /* enable only MTL interrupt realted to - * Constant Gate Control Error - * Head-Of-Line Blocking due to Scheduling - * Head-Of-Line Blocking due to Frame Size - * BTR Error - * Switch to S/W owned list Complete - */ - mtl_est_ir |= (EQOS_MTL_EST_ITRE_CGCE | EQOS_MTL_EST_ITRE_IEHS | - EQOS_MTL_EST_ITRE_IEHF | EQOS_MTL_EST_ITRE_IEBE | - EQOS_MTL_EST_ITRE_IECC); - osi_writela(osi_core, mtl_est_ir, - (unsigned char *)addr + EQOS_MTL_EST_ITRE); -} - -/** - * @brief eqos_enable_fpe_interrupts - Enable MTL interrupts - * - * Algorithm: enable FPE interrupts - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void eqos_enable_fpe_interrupts( - struct osi_core_priv_data *const osi_core) -{ - unsigned int value = OSI_DISABLE; - void *addr = osi_core->base; - - /* Read MAC IER Register and enable Frame Preemption Interrupt - * Enable */ - value = osi_readla(osi_core, (unsigned char *)addr + EQOS_MAC_IMR); - value |= EQOS_IMR_FPEIE; - osi_writela(osi_core, value, (unsigned char *)addr + EQOS_MAC_IMR); -} - -/** - * @brief eqos_save_gcl_params - save GCL configs in local core structure - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void eqos_save_gcl_params(struct osi_core_priv_data *osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int gcl_widhth[4] = {0, OSI_MAX_24BITS, OSI_MAX_28BITS, - OSI_MAX_32BITS}; - nveu32_t gcl_ti_mask[4] = {0, OSI_MASK_16BITS, OSI_MASK_20BITS, - OSI_MASK_24BITS}; - unsigned int gcl_depthth[6] = {0, OSI_GCL_SIZE_64, OSI_GCL_SIZE_128, - OSI_GCL_SIZE_256, OSI_GCL_SIZE_512, - OSI_GCL_SIZE_1024}; - - if ((osi_core->hw_feature->gcl_width == 0) || - (osi_core->hw_feature->gcl_width > 3)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL width\n", - (unsigned long long)osi_core->hw_feature->gcl_width); - } else { - l_core->gcl_width_val = - gcl_widhth[osi_core->hw_feature->gcl_width]; - l_core->ti_mask = gcl_ti_mask[osi_core->hw_feature->gcl_width]; - } - - if ((osi_core->hw_feature->gcl_depth == 0) || - (osi_core->hw_feature->gcl_depth > 5)) { - /* Do Nothing */ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL depth\n", - (unsigned long long)osi_core->hw_feature->gcl_depth); - } else { - l_core->gcl_dep = gcl_depthth[osi_core->hw_feature->gcl_depth]; - } -} - -/** - * @brief eqos_tsn_init - initialize TSN feature - * - * Algorithm: - * 1) If hardware support EST, - * a) Set default EST configuration - * b) Set enable interrupts - * 2) If hardware supports FPE - * a) Set default FPE configuration - * b) enable interrupts - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est_sel: EST HW support present or not - * @param[in] fpe_sel: FPE HW support present or not - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void eqos_tsn_init(struct osi_core_priv_data *osi_core, - unsigned int est_sel, unsigned int fpe_sel) -{ - unsigned int val = 0x0; - unsigned int temp = 0U; - - if (est_sel == OSI_ENABLE) { - eqos_save_gcl_params(osi_core); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - EQOS_MTL_EST_CONTROL); - - /* - * PTOV PTP clock period * 6 - * dual-port RAM based asynchronous FIFO controllers or - * Single-port RAM based synchronous FIFO controllers - * CTOV 96 x Tx clock period - * : - * : - * set other default value - */ - val &= ~EQOS_MTL_EST_CONTROL_PTOV; - if (osi_core->pre_si == OSI_ENABLE) { - /* 6*1/(78.6 MHz) in ns*/ - temp = (6U * 13U); - } else { - temp = EQOS_MTL_EST_PTOV_RECOMMEND; - } - temp = temp << EQOS_MTL_EST_CONTROL_PTOV_SHIFT; - val |= temp; - - val &= ~EQOS_MTL_EST_CONTROL_CTOV; - temp = EQOS_MTL_EST_CTOV_RECOMMEND; - temp = temp << EQOS_MTL_EST_CONTROL_CTOV_SHIFT; - val |= temp; - - /*Loop Count to report Scheduling Error*/ - val &= ~EQOS_MTL_EST_CONTROL_LCSE; - val |= EQOS_MTL_EST_CONTROL_LCSE_VAL; - - val &= ~(EQOS_MTL_EST_CONTROL_DDBF | - EQOS_MTL_EST_CONTROL_DFBS); - val |= EQOS_MTL_EST_CONTROL_DDBF; - - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_OVERHEAD); - val &= ~EQOS_MTL_EST_OVERHEAD_OVHD; - /* As per hardware team recommendation */ - val |= EQOS_MTL_EST_OVERHEAD_RECOMMEND; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_OVERHEAD); - - eqos_enable_mtl_interrupts(osi_core); - } - - if (fpe_sel == OSI_ENABLE) { - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - EQOS_MAC_RQC1R); - val &= ~EQOS_MAC_RQC1R_FPRQ; - temp = osi_core->residual_queue; - temp = temp << EQOS_MAC_RQC1R_FPRQ_SHIFT; - temp = (temp & EQOS_MAC_RQC1R_FPRQ); - val |= temp; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - EQOS_MAC_RQC1R); - - eqos_enable_fpe_interrupts(osi_core); - } - - /* CBS setting for TC should be by user application/IOCTL as - * per requirement */ -} - -/** - * @brief Map DMA channels to a specific VM IRQ. - * - * @param[in] osi_core: OSI private data structure. - * - * @note - * Dependencies: OSD layer needs to update number of VM channels and - * DMA channel list in osi_vm_irq_data. - * Protection: None. - * - * @retval None. - */ -static void eqos_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) -{ - struct osi_vm_irq_data *irq_data; - nveu32_t i, j; - nveu32_t chan; - - if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) { - return; - } - - for (i = 0; i < osi_core->num_vm_irqs; i++) { - irq_data = &osi_core->irq_data[i]; - for (j = 0; j < irq_data->num_vm_chans; j++) { - chan = irq_data->vm_chans[j]; - if (chan >= OSI_EQOS_MAX_NUM_CHANS) { - continue; - } - osi_writel(OSI_BIT(irq_data->vm_num), - (nveu8_t *)osi_core->base + - EQOS_VIRT_INTR_APB_CHX_CNTRL(chan)); - } - osi_writel(OSI_BIT(irq_data->vm_num), - (nveu8_t *)osi_core->base + VIRTUAL_APB_ERR_CTRL); - } -} - -/** - * @brief eqos_core_init - EQOS MAC, MTL and common DMA Initialization - * - * @note - * Algorithm: - * - This function will take care of initializing MAC, MTL and - * common DMA registers. - * - Refer to OSI column of <> for sequence - * of execution. - * - TraceID:ETHERNET_NVETHERNETRM_006 - * - * @param[in] osi_core: OSI core private data structure. Used params are - * - base, dcs_en, num_mtl_queues, mtl_queues, mtu, stip_vlan_tag, pause_frames, l3l4_filter_bitmask - * @param[in] tx_fifo_size: MTL TX FIFO size. Max 11. - * @param[in] rx_fifo_size: MTL RX FIFO size. Max 11. - * - * @pre - * - MAC should be out of reset. See osi_poll_for_mac_reset_complete() - * for details. - * - osi_core->base needs to be filled based on ioremap. - * - osi_core->num_mtl_queues needs to be filled. - * - osi_core->mtl_queues[qinx] need to be filled. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_core_init(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_fifo_size, - const nveu32_t rx_fifo_size) -{ - nve32_t ret = 0; - nveu32_t qinx = 0; - nveu32_t value = 0; - nveu32_t value1 = 0; - nveu32_t tx_fifo = 0; - nveu32_t rx_fifo = 0; - - eqos_core_safety_init(osi_core); - eqos_core_backup_init(osi_core); - -#ifndef UPDATED_PAD_CAL - /* PAD calibration */ - ret = eqos_pad_calibrate(osi_core); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "eqos pad calibration failed\n", 0ULL); - return ret; - } -#endif /* !UPDATED_PAD_CAL */ - - /* reset mmc counters */ - osi_writela(osi_core, EQOS_MMC_CNTRL_CNTRST, - (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - - if (osi_core->use_virtualization == OSI_DISABLE) { - if (osi_core->hv_base != OSI_NULL) { - osi_writela(osi_core, EQOS_5_30_ASID_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - EQOS_AXI_ASID_CTRL); - - osi_writela(osi_core, EQOS_5_30_ASID1_CTRL_VAL, - (nveu8_t *)osi_core->hv_base + - EQOS_AXI_ASID1_CTRL); - } - - if (osi_core->mac_ver < OSI_EQOS_MAC_5_30) { - /* AXI ASID CTRL for channel 0 to 3 */ - osi_writela(osi_core, EQOS_AXI_ASID_CTRL_VAL, - (nveu8_t *)osi_core->base + - EQOS_AXI_ASID_CTRL); - - /* AXI ASID1 CTRL for channel 4 to 7 */ - if (osi_core->mac_ver > OSI_EQOS_MAC_5_00) { - osi_writela(osi_core, EQOS_AXI_ASID1_CTRL_VAL, - (nveu8_t *)osi_core->base + - EQOS_AXI_ASID1_CTRL); - } - } - } - - /* Mapping MTL Rx queue and DMA Rx channel */ - if (osi_core->dcs_en == OSI_ENABLE) { - value = EQOS_RXQ_TO_DMA_CHAN_MAP_DCS_EN; - value1 = EQOS_RXQ_TO_DMA_CHAN_MAP1_DCS_EN; - } else { - value = EQOS_RXQ_TO_DMA_CHAN_MAP; - value1 = EQOS_RXQ_TO_DMA_CHAN_MAP1; - } - - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_RXQ_DMA_MAP0, - EQOS_MTL_RXQ_DMA_MAP0_IDX); - - if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { - eqos_core_safety_writel(osi_core, value1, - (nveu8_t *)osi_core->base + - EQOS_MTL_RXQ_DMA_MAP1, - EQOS_MTL_RXQ_DMA_MAP1_IDX); - } - - if (osi_unlikely(osi_core->num_mtl_queues > OSI_EQOS_MAX_NUM_QUEUES)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Number of queues is incorrect\n", 0ULL); - return -1; - } - - /* Calculate value of Transmit queue fifo size to be programmed */ - tx_fifo = eqos_calculate_per_queue_fifo(osi_core->mac_ver, - tx_fifo_size, - osi_core->num_mtl_queues); - /* Calculate value of Receive queue fifo size to be programmed */ - rx_fifo = eqos_calculate_per_queue_fifo(osi_core->mac_ver, - rx_fifo_size, - osi_core->num_mtl_queues); - - /* Configure MTL Queues */ - for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { - if (osi_unlikely(osi_core->mtl_queues[qinx] >= - OSI_EQOS_MAX_NUM_QUEUES)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Incorrect queues number\n", 0ULL); - return -1; - } - ret = eqos_configure_mtl_queue(osi_core->mtl_queues[qinx], - osi_core, tx_fifo, rx_fifo); - if (ret < 0) { - return ret; - } - } - - /* configure EQOS MAC HW */ - eqos_configure_mac(osi_core); - - /* configure EQOS DMA */ - eqos_configure_dma(osi_core); - - /* tsn initialization */ - if (osi_core->hw_feature != OSI_NULL) { - eqos_tsn_init(osi_core, osi_core->hw_feature->est_sel, - osi_core->hw_feature->fpe_sel); - } - - /* initialize L3L4 Filters variable */ - osi_core->l3l4_filter_bitmask = OSI_NONE; - - eqos_dma_chan_to_vmirq_map(osi_core); - - return ret; -} - -/** - * @brief eqos_handle_mac_fpe_intrs - * - * Algorithm: This function takes care of handling the - * MAC FPE interrupts. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC interrupts need to be enabled - */ -static void eqos_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) -{ - unsigned int val = 0; - - /* interrupt bit clear on read as CSR_SW is reset */ - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); - - if ((val & EQOS_MAC_FPE_CTS_RVER) == EQOS_MAC_FPE_CTS_RVER) { - val &= ~EQOS_MAC_FPE_CTS_RVER; - val |= EQOS_MAC_FPE_CTS_SRSP; - } - - if ((val & EQOS_MAC_FPE_CTS_RRSP) == EQOS_MAC_FPE_CTS_RRSP) { - /* received respose packet Nothing to be done, it means other - * IP also support FPE - */ - val &= ~EQOS_MAC_FPE_CTS_RRSP; - val &= ~EQOS_MAC_FPE_CTS_TVER; - osi_core->fpe_ready = OSI_ENABLE; - val |= EQOS_MAC_FPE_CTS_EFPE; - } - - if ((val & EQOS_MAC_FPE_CTS_TRSP) == EQOS_MAC_FPE_CTS_TRSP) { - /* TX response packet sucessful */ - osi_core->fpe_ready = OSI_ENABLE; - /* Enable frame preemption */ - val &= ~EQOS_MAC_FPE_CTS_TRSP; - val &= ~EQOS_MAC_FPE_CTS_TVER; - val |= EQOS_MAC_FPE_CTS_EFPE; - } - - if ((val & EQOS_MAC_FPE_CTS_TVER) == EQOS_MAC_FPE_CTS_TVER) { - /*Transmit verif packet sucessful*/ - osi_core->fpe_ready = OSI_DISABLE; - val &= ~EQOS_MAC_FPE_CTS_TVER; - val &= ~EQOS_MAC_FPE_CTS_EFPE; - } - - osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); -} - -/** - * @brief eqos_handle_mac_intrs - Handle MAC interrupts - * - * @note - * Algorithm: - * - This function takes care of handling the - * MAC interrupts to configure speed, mode for linkup use case. - * - Ignore handling for following cases: - * - If no MAC interrupt in dma_isr, - * - RGMII/SMII MAC interrupt - * - If link is down - * - Identify speed and mode changes from EQOS_MAC_PCS register and configure the same by calling - * eqos_set_speed(), eqos_set_mode()(proceed even on error for this call) API's. - * - SWUD_ID: ETHERNET_NVETHERNETRM_010_1 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] dma_isr: DMA ISR register read value. - * - * @pre MAC interrupts need to be enabled - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_handle_mac_intrs(struct osi_core_priv_data *const osi_core, - nveu32_t dma_isr) -{ - nveu32_t mac_imr = 0; - nveu32_t mac_pcs = 0; - nveu32_t mac_isr = 0; - nve32_t ret = 0; -#ifdef HSI_SUPPORT - nveu64_t tx_frame_err = 0; -#endif - mac_isr = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_ISR); - -#ifdef HSI_SUPPORT - if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { - /* T23X-EQOS_HSIv2-19: Consistency Monitor for TX Frame */ - if ((dma_isr & EQOS_DMA_ISR_TXSTSIS) == EQOS_DMA_ISR_TXSTSIS) { - osi_core->hsi.tx_frame_err_count = - osi_update_stats_counter(osi_core->hsi.tx_frame_err_count, - 1UL); - tx_frame_err = osi_core->hsi.tx_frame_err_count / - osi_core->hsi.err_count_threshold; - if (osi_core->hsi.tx_frame_err_threshold < tx_frame_err) { - osi_core->hsi.tx_frame_err_threshold = tx_frame_err; - osi_core->hsi.report_count_err[TX_FRAME_ERR_IDX] = OSI_ENABLE; - } - osi_core->hsi.err_code[TX_FRAME_ERR_IDX] = - OSI_TX_FRAME_ERR; - osi_core->hsi.report_err = OSI_ENABLE; - } - } -#endif - /* Handle MAC interrupts */ - if ((dma_isr & EQOS_DMA_ISR_MACIS) != EQOS_DMA_ISR_MACIS) { - return; - } - - /* handle only those MAC interrupts which are enabled */ - mac_imr = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_IMR); - mac_isr = (mac_isr & mac_imr); - - /* RGMII/SMII interrupt */ - if (((mac_isr & EQOS_MAC_ISR_RGSMIIS) != EQOS_MAC_ISR_RGSMIIS) && - ((mac_isr & EQOS_MAC_IMR_FPEIS) != EQOS_MAC_IMR_FPEIS)) { - return; - } - - if (((mac_isr & EQOS_MAC_IMR_FPEIS) == EQOS_MAC_IMR_FPEIS) && - ((mac_imr & EQOS_IMR_FPEIE) == EQOS_IMR_FPEIE)) { - eqos_handle_mac_fpe_intrs(osi_core); - mac_isr &= ~EQOS_MAC_IMR_FPEIS; - } - osi_writela(osi_core, mac_isr, - (nveu8_t *) osi_core->base + EQOS_MAC_ISR); - - mac_pcs = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_PCS); - /* check whether Link is UP or NOT - if not return. */ - if ((mac_pcs & EQOS_MAC_PCS_LNKSTS) != EQOS_MAC_PCS_LNKSTS) { - return; - } - - /* check for Link mode (full/half duplex) */ - if ((mac_pcs & EQOS_MAC_PCS_LNKMOD) == EQOS_MAC_PCS_LNKMOD) { - ret = eqos_set_mode(osi_core, OSI_FULL_DUPLEX); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set mode in full duplex failed\n", 0ULL); - } - } else { - ret = eqos_set_mode(osi_core, OSI_HALF_DUPLEX); - if (osi_unlikely(ret < 0)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "set mode in half duplex failed\n", 0ULL); - } - } - - /* set speed at MAC level */ - /* TODO: set_tx_clk needs to be done */ - /* Maybe through workqueue for QNX */ - if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == EQOS_MAC_PCS_LNKSPEED_10) { - eqos_set_speed(osi_core, OSI_SPEED_10); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == - EQOS_MAC_PCS_LNKSPEED_100) { - eqos_set_speed(osi_core, OSI_SPEED_100); - } else if ((mac_pcs & EQOS_MAC_PCS_LNKSPEED) == - EQOS_MAC_PCS_LNKSPEED_1000) { - eqos_set_speed(osi_core, OSI_SPEED_1000); - } else { - /* Nothing here */ - } - - if (((mac_isr & EQOS_MAC_IMR_FPEIS) == EQOS_MAC_IMR_FPEIS) && - ((mac_imr & EQOS_IMR_FPEIE) == EQOS_IMR_FPEIE)) { - eqos_handle_mac_fpe_intrs(osi_core); - mac_isr &= ~EQOS_MAC_IMR_FPEIS; - } - osi_writela(osi_core, mac_isr, - (unsigned char *)osi_core->base + EQOS_MAC_ISR); -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief update_dma_sr_stats - stats for dma_status error - * - * @note - * Algorithm: - * - increment error stats based on corresponding bit filed. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] dma_sr: Dma status register read value - * @param[in] qinx: Queue index - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void update_dma_sr_stats( - struct osi_core_priv_data *const osi_core, - nveu32_t dma_sr, nveu32_t qinx) -{ - nveu64_t 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); - } -} -/** \endcond */ - -/** - * @brief eqos_handle_mtl_intrs - Handle MTL interrupts - * - * Algorithm: Code to handle interrupt for MTL EST error and status. - * There are possible 4 errors which can be part of common interrupt in case of - * MTL_EST_SCH_ERR (sheduling error)- HLBS - * MTL_EST_FRMS_ERR (Frame size error) - HLBF - * MTL_EST_FRMC_ERR (frame check error) - HLBF - * Constant Gate Control Error - when time interval in less - * than or equal to cycle time, llr = 1 - * There is one status interrupt which says swich to SWOL complete. - * - * @param[in] osi_core: osi core priv data structure - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void eqos_handle_mtl_intrs(struct osi_core_priv_data *osi_core) -{ - unsigned int val = 0U; - unsigned int sch_err = 0U; - unsigned int frm_err = 0U; - unsigned int temp = 0U; - unsigned int i = 0; - unsigned long stat_val = 0U; - unsigned int value = 0U; - - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_EST_STATUS); - val &= (EQOS_MTL_EST_STATUS_CGCE | EQOS_MTL_EST_STATUS_HLBS | - EQOS_MTL_EST_STATUS_HLBF | EQOS_MTL_EST_STATUS_BTRE | - EQOS_MTL_EST_STATUS_SWLC); - - /* return if interrupt is not related to EST */ - if (val == OSI_DISABLE) { - return; - } - - /* increase counter write 1 back will clear */ - if ((val & EQOS_MTL_EST_STATUS_CGCE) == EQOS_MTL_EST_STATUS_CGCE) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.const_gate_ctr_err; - osi_core->tsn_stats.const_gate_ctr_err = - osi_update_stats_counter(stat_val, 1U); - } - - if ((val & EQOS_MTL_EST_STATUS_HLBS) == EQOS_MTL_EST_STATUS_HLBS) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.head_of_line_blk_sch; - osi_core->tsn_stats.head_of_line_blk_sch = - osi_update_stats_counter(stat_val, 1U); - /* Need to read MTL_EST_Sch_Error register and cleared */ - sch_err = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_SCH_ERR); - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - temp = OSI_ENABLE; - temp = temp << i; - if ((sch_err & temp) == temp) { - stat_val = osi_core->tsn_stats.hlbs_q[i]; - osi_core->tsn_stats.hlbs_q[i] = - osi_update_stats_counter(stat_val, 1U); - } - } - sch_err &= 0xFFU; /* only 8 TC allowed so clearing all */ - osi_writela(osi_core, sch_err, - (nveu8_t *)osi_core->base + EQOS_MTL_EST_SCH_ERR); - /* Disable est as error happen */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - /* DBFS 0 means do not packet */ - if ((value & EQOS_MTL_EST_CONTROL_DFBS) == OSI_DISABLE) { - value &= ~EQOS_MTL_EST_CONTROL_EEST; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Disabling EST due to HLBS, correct GCL\n", - OSI_NONE); - } - } - - if ((val & EQOS_MTL_EST_STATUS_HLBF) == EQOS_MTL_EST_STATUS_HLBF) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.head_of_line_blk_frm; - osi_core->tsn_stats.head_of_line_blk_frm = - osi_update_stats_counter(stat_val, 1U); - /* Need to read MTL_EST_Frm_Size_Error register and cleared */ - frm_err = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_FRMS_ERR); - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - temp = OSI_ENABLE; - temp = temp << i; - if ((frm_err & temp) == temp) { - stat_val = osi_core->tsn_stats.hlbf_q[i]; - osi_core->tsn_stats.hlbf_q[i] = - osi_update_stats_counter(stat_val, 1U); - } - } - frm_err &= 0xFFU; /* 8 TC allowed so clearing all */ - osi_writela(osi_core, frm_err, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_FRMS_ERR); - /* Disable est as error happen */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - /* DDBF 1 means don't drop packet */ - if ((value & EQOS_MTL_EST_CONTROL_DDBF) == - EQOS_MTL_EST_CONTROL_DDBF) { - value &= ~EQOS_MTL_EST_CONTROL_EEST; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Disabling EST due to HLBF, correct GCL\n", - OSI_NONE); - } - } - - if ((val & EQOS_MTL_EST_STATUS_SWLC) == EQOS_MTL_EST_STATUS_SWLC) { - if ((val & EQOS_MTL_EST_STATUS_BTRE) != - EQOS_MTL_EST_STATUS_BTRE) { - osi_core->est_ready = OSI_ENABLE; - } - stat_val = osi_core->tsn_stats.sw_own_list_complete; - osi_core->tsn_stats.sw_own_list_complete = - osi_update_stats_counter(stat_val, 1U); - } - - if ((val & EQOS_MTL_EST_STATUS_BTRE) == EQOS_MTL_EST_STATUS_BTRE) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.base_time_reg_err; - osi_core->tsn_stats.base_time_reg_err = - osi_update_stats_counter(stat_val, 1U); - osi_core->est_ready = OSI_DISABLE; - } - /* clear EST status register as interrupt is handled */ - osi_writela(osi_core, val, - (nveu8_t *)osi_core->base + EQOS_MTL_EST_STATUS); -} - -#ifdef HSI_SUPPORT -/** - * @brief eqos_handle_hsi_intr - Handles HSI interrupt. - * - * @note - * Algorithm: - * - Clear HSI interrupt source. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_handle_hsi_intr(struct osi_core_priv_data *const osi_core) -{ - nveu32_t val = 0U; - nveu32_t val2 = 0U; - nveu64_t ce_count_threshold; - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_STATUS); - if (((val & EQOS_REGISTER_PARITY_ERR) == EQOS_REGISTER_PARITY_ERR) || - ((val & EQOS_CORE_UNCORRECTABLE_ERR) == EQOS_CORE_UNCORRECTABLE_ERR)) { - osi_core->hsi.err_code[UE_IDX] = - hsi_err_code[osi_core->instance_id][UE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.report_count_err[UE_IDX] = OSI_ENABLE; - /* Disable the interrupt */ - val2 = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - val2 &= ~EQOS_REGISTER_PARITY_ERR; - val2 &= ~EQOS_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, val2, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_ENABLE); - } - if ((val & EQOS_CORE_CORRECTABLE_ERR) == EQOS_CORE_CORRECTABLE_ERR) { - osi_core->hsi.err_code[CE_IDX] = - hsi_err_code[osi_core->instance_id][CE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.ce_count = - osi_update_stats_counter(osi_core->hsi.ce_count, 1UL); - ce_count_threshold = osi_core->hsi.ce_count / osi_core->hsi.err_count_threshold; - if (osi_core->hsi.ce_count_threshold < ce_count_threshold) { - osi_core->hsi.ce_count_threshold = ce_count_threshold; - osi_core->hsi.report_count_err[CE_IDX] = OSI_ENABLE; - } - } - val &= ~EQOS_MAC_SBD_INTR; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_STATUS); - - if (((val & EQOS_CORE_CORRECTABLE_ERR) == EQOS_CORE_CORRECTABLE_ERR) || - ((val & EQOS_CORE_UNCORRECTABLE_ERR) == EQOS_CORE_UNCORRECTABLE_ERR)) { - - /* Clear FSM error status. Clear on read */ - (void)osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_DPP_FSM_INTERRUPT_STATUS); - - /* Clear ECC error status register */ - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_ECC_INTERRUPT_STATUS); - if (val != 0U) { - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_MTL_ECC_INTERRUPT_STATUS); - } - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_DMA_ECC_INTERRUPT_STATUS); - if (val != 0U) { - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_DMA_ECC_INTERRUPT_STATUS); - } - } -} -#endif - -/** - * @brief eqos_handle_common_intr - Handles common interrupt. - * - * @note - * Algorithm: - * - Reads DMA ISR register - * - Returns if calue is 0. - * - Handle Non-TI/RI interrupts for all MTL queues and increments #osi_core_priv_data->xstats - * based on error detected per cahnnel. - * - Calls eqos_handle_mac_intrs() to handle MAC interrupts. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_010 - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_handle_common_intr(struct osi_core_priv_data *const osi_core) -{ - void *base = osi_core->base; - nveu32_t dma_isr = 0; - nveu32_t qinx = 0; - nveu32_t i = 0; - nveu32_t dma_sr = 0; - nveu32_t dma_ier = 0; - nveu32_t mtl_isr = 0; - nveu32_t frp_isr = 0U; - - if (osi_core->mac_ver >= OSI_EQOS_MAC_5_30) { - osi_writela(osi_core, EQOS_MAC_SBD_INTR, (nveu8_t *)osi_core->base + - EQOS_WRAP_COMMON_INTR_STATUS); -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - eqos_handle_hsi_intr(osi_core); - } -#endif - } - - dma_isr = osi_readla(osi_core, (nveu8_t *)base + EQOS_DMA_ISR); - if (dma_isr == 0U) { - return; - } - - //FIXME Need to check how we can get the DMA channel here instead of - //MTL Queues - if ((dma_isr & EQOS_DMA_CHAN_INTR_STATUS) != 0U) { - /* Handle Non-TI/RI interrupts */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - qinx = osi_core->mtl_queues[i]; - if (qinx >= OSI_EQOS_MAX_NUM_CHANS) { - continue; - } - - /* read dma channel status register */ - dma_sr = osi_readla(osi_core, (nveu8_t *)base + - EQOS_DMA_CHX_STATUS(qinx)); - /* read dma channel interrupt enable register */ - dma_ier = osi_readla(osi_core, (nveu8_t *)base + - EQOS_DMA_CHX_IER(qinx)); - - /* process only those interrupts which we - * have enabled. - */ - dma_sr = (dma_sr & dma_ier); - - /* mask off RI and TI */ - dma_sr &= ~(OSI_BIT(6) | OSI_BIT(0)); - if (dma_sr == 0U) { - continue; - } - - /* ack non ti/ri ints */ - osi_writela(osi_core, dma_sr, (nveu8_t *)base + - EQOS_DMA_CHX_STATUS(qinx)); - update_dma_sr_stats(osi_core, dma_sr, qinx); - } - } - - eqos_handle_mac_intrs(osi_core, dma_isr); - /* Handle MTL inerrupts */ - mtl_isr = osi_readla(osi_core, - (unsigned char *)base + EQOS_MTL_INTR_STATUS); - if (((mtl_isr & EQOS_MTL_IS_ESTIS) == EQOS_MTL_IS_ESTIS) && - ((dma_isr & EQOS_DMA_ISR_MTLIS) == EQOS_DMA_ISR_MTLIS)) { - eqos_handle_mtl_intrs(osi_core); - mtl_isr &= ~EQOS_MTL_IS_ESTIS; - osi_writela(osi_core, mtl_isr, (unsigned char *)base + - EQOS_MTL_INTR_STATUS); - } - - /* Clear FRP Interrupt MTL_RXP_Interrupt_Control_Status */ - frp_isr = osi_readla(osi_core, - (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); - frp_isr |= (EQOS_MTL_RXP_INTR_CS_NVEOVIS | - EQOS_MTL_RXP_INTR_CS_NPEOVIS | - EQOS_MTL_RXP_INTR_CS_FOOVIS | - EQOS_MTL_RXP_INTR_CS_PDRFIS); - osi_writela(osi_core, frp_isr, - (unsigned char *)base + EQOS_MTL_RXP_INTR_CS); -} - -/** - * @brief eqos_start_mac - Start MAC Tx/Rx engine - * - * @note - * Algorithm: - * - Enable MAC Transmitter and Receiver in EQOS_MAC_MCR_IDX - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_008 - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_start_mac(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - void *addr = osi_core->base; - - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - /* Enable MAC Transmit */ - /* Enable MAC Receive */ - value |= EQOS_MCR_TE | EQOS_MCR_RE; - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); -} - -/** - * @brief eqos_stop_mac - Stop MAC Tx/Rx engine - * - * @note - * Algorithm: - * - Disable MAC Transmitter and Receiver in EQOS_MAC_MCR_IDX - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_007 - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC DMA deinit should be complete. See osi_hw_dma_deinit() - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - */ -static void eqos_stop_mac(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - void *addr = osi_core->base; - - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - /* Disable MAC Transmit */ - /* Disable MAC Receive */ - value &= ~EQOS_MCR_TE; - value &= ~EQOS_MCR_RE; - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); -} - -#ifdef MACSEC_SUPPORT -/** - * @brief eqos_config_mac_tx - Enable/Disable MAC Tx - * - * @note - * Algorithm: - * - Enable or Disables MAC Transmitter - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Enable or Disable.MAC Tx - * - * @pre MAC init should be complete. See osi_hw_core_init() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_config_mac_tx(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value; - void *addr = osi_core->base; - - if (enable == OSI_ENABLE) { - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - /* Enable MAC Transmit */ - value |= EQOS_MCR_TE; - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - } else { - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - /* Disable MAC Transmit */ - value &= ~EQOS_MCR_TE; - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - } -} -#endif /* MACSEC_SUPPORT */ - -/** - * @brief eqos_config_l2_da_perfect_inverse_match - configure register for - * inverse or perfect match. - * - * @note - * Algorithm: - * - use perfect_inverse_match filed to set perfect/inverse matching for L2 DA. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_018 - * - * @param[in] base: Base address from OSI core private data structure. - * @param[in] perfect_inverse_match: OSI_INV_MATCH - inverse mode else - perfect mode - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 always - */ -static inline nve32_t eqos_config_l2_da_perfect_inverse_match( - struct osi_core_priv_data *const osi_core, - nveu32_t perfect_inverse_match) -{ - nveu32_t value = 0U; - - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_PFR); - value &= ~EQOS_MAC_PFR_DAIF; - if (perfect_inverse_match == OSI_INV_MATCH) { - value |= EQOS_MAC_PFR_DAIF; - } - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MAC_PFR, - EQOS_MAC_PFR_IDX); - - return 0; -} - -/** - * @brief eqos_config_mac_pkt_filter_reg - configure mac filter register. - * - * @note - * - This sequence is used to configure MAC in different pkt - * processing modes like promiscuous, multicast, unicast, - * hash unicast/multicast based on input filter arguments. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_018 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] filter: OSI filter structure. used param oper_mode. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 always - */ -static nve32_t eqos_config_mac_pkt_filter_reg( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - nveu32_t value = 0U; - nve32_t ret = 0; - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_PFR); - - /*Retain all other values */ - value &= (EQOS_MAC_PFR_DAIF | EQOS_MAC_PFR_DBF | EQOS_MAC_PFR_SAIF | - EQOS_MAC_PFR_SAF | EQOS_MAC_PFR_PCF | EQOS_MAC_PFR_VTFE | - EQOS_MAC_PFR_IPFE | EQOS_MAC_PFR_DNTU | EQOS_MAC_PFR_RA); - - if ((filter->oper_mode & OSI_OPER_EN_PROMISC) != OSI_DISABLE) { - value |= EQOS_MAC_PFR_PR; - } - - if ((filter->oper_mode & OSI_OPER_DIS_PROMISC) != OSI_DISABLE) { - value &= ~EQOS_MAC_PFR_PR; - } - - if ((filter->oper_mode & OSI_OPER_EN_ALLMULTI) != OSI_DISABLE) { - value |= EQOS_MAC_PFR_PM; - } - - if ((filter->oper_mode & OSI_OPER_DIS_ALLMULTI) != OSI_DISABLE) { - value &= ~EQOS_MAC_PFR_PM; - } - - if ((filter->oper_mode & OSI_OPER_EN_PERFECT) != OSI_DISABLE) { - value |= EQOS_MAC_PFR_HPF; - } - - if ((filter->oper_mode & OSI_OPER_DIS_PERFECT) != OSI_DISABLE) { - value &= ~EQOS_MAC_PFR_HPF; - } - - - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_PFR, EQOS_MAC_PFR_IDX); - - if ((filter->oper_mode & OSI_OPER_EN_L2_DA_INV) != OSI_DISABLE) { - ret = eqos_config_l2_da_perfect_inverse_match(osi_core, - OSI_INV_MATCH); - } - - if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != OSI_DISABLE) { - ret = eqos_config_l2_da_perfect_inverse_match(osi_core, - OSI_PFT_MATCH); - } - - return ret; -} - -/** - * @brief eqos_update_mac_addr_helper - Function to update DCS and MBC; helper function for - * eqos_update_mac_addr_low_high_reg() - * - * @note - * Algorithm: - * - Validation of dma_chan if dma_routing_enable is OSI_ENABLE and addr_mask - * - corresponding sections not updated if invalid. - * - This helper routine is to update value parameter based on DCS and MBC - * sections of L2 register. - * dsc_en status performed before updating DCS bits. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_018 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[out] value: nveu32_t pointer which has value read from register. - * @param[in] idx: Refer #osi_filter->index for details. - * @param[in] dma_routing_enable: Refer #osi_filter->dma_routing for details. - * @param[in] dma_chan: Refer #osi_filter->dma_chan for details. - * @param[in] addr_mask: Refer #osi_filter->addr_mask for details. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t eqos_update_mac_addr_helper( - const struct osi_core_priv_data *osi_core, - nveu32_t *value, - const nveu32_t idx, - const nveu32_t dma_chan, - const nveu32_t addr_mask, - OSI_UNUSED const nveu32_t src_dest) -{ - nveu32_t temp; - - /* PDC bit of MAC_Ext_Configuration register is set so binary - * value representation form index 32-127 else hot-bit - * representation. - */ - if ((idx < EQOS_MAX_MAC_ADDR_REG) && - (osi_core->mac_ver >= OSI_EQOS_MAC_5_00)) { - *value &= EQOS_MAC_ADDRH_DCS; - temp = OSI_BIT(dma_chan); - temp = temp << EQOS_MAC_ADDRH_DCS_SHIFT; - temp = temp & EQOS_MAC_ADDRH_DCS; - *value = *value | temp; - } else { - *value = OSI_DISABLE; - temp = dma_chan; - temp = temp << EQOS_MAC_ADDRH_DCS_SHIFT; - temp = temp & EQOS_MAC_ADDRH_DCS; - *value = temp; - } - - /* Address mask is valid for address 1 to 31 index only */ - if ((addr_mask <= EQOS_MAX_MASK_BYTE) && - (addr_mask > OSI_AMASK_DISABLE)) { - if ((idx > 0U) && (idx < EQOS_MAX_MAC_ADDR_REG)) { - *value = (*value | - ((addr_mask << EQOS_MAC_ADDRH_MBC_SHIFT) & - EQOS_MAC_ADDRH_MBC)); - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address index for MBC\n", - 0ULL); - return -1; - } - } - - return 0; -} - -/** - * @brief eqos_l2_filter_delete - Function to delete L2 filter - * - * @note - * Algorithm: - * - This helper routine is to delete L2 filter based on DCS and MBC - * parameter. - * - Handling for EQOS mac version 4.10 differently. - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] value: nveu32_t pointer which has value read from register. - * @param[in] idx: filter index - * @param[in] dma_routing_enable: dma channel routing enable(1) - * @param[in] dma_chan: dma channel number - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_l2_filter_delete(struct osi_core_priv_data *osi_core, - nveu32_t *value, - const nveu32_t idx, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan) -{ - nveu32_t dcs_check = *value; - nveu32_t temp = OSI_DISABLE; - - osi_writela(osi_core, OSI_MAX_32BITS, - (nveu8_t *)osi_core->base + EQOS_MAC_ADDRL((idx))); - - *value |= OSI_MASK_16BITS; - if (dma_routing_enable == OSI_DISABLE || - osi_core->mac_ver < OSI_EQOS_MAC_5_00) { - *value &= ~(EQOS_MAC_ADDRH_AE | EQOS_MAC_ADDRH_DCS); - osi_writela(osi_core, *value, (nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - return; - } - - dcs_check &= EQOS_MAC_ADDRH_DCS; - dcs_check = dcs_check >> EQOS_MAC_ADDRH_DCS_SHIFT; - - if (idx >= EQOS_MAX_MAC_ADDR_REG) { - dcs_check = OSI_DISABLE; - } else { - temp = OSI_BIT(dma_chan); - dcs_check &= ~(temp); - } - - if (dcs_check == OSI_DISABLE) { - *value &= ~(EQOS_MAC_ADDRH_AE | EQOS_MAC_ADDRH_DCS); - osi_writela(osi_core, *value, (nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - } else { - *value &= ~(EQOS_MAC_ADDRH_DCS); - *value |= (dcs_check << EQOS_MAC_ADDRH_DCS_SHIFT); - osi_writela(osi_core, *value, (nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - } - - return; -} - -/** - * @brief eqos_update_mac_addr_low_high_reg- Update L2 address in filter - * register - * - * @note - * Algorithm: - * - This routine validates index and addr of #osi_filter. - * - calls eqos_update_mac_addr_helper() to update DCS and MBS. - * dsc_en status performed before updating DCS bits. - * - Update MAC address to L2 filter register. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_018 - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_update_mac_addr_low_high_reg( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - nveu32_t idx = filter->index; - nveu32_t dma_routing_enable = filter->dma_routing; - nveu32_t dma_chan = filter->dma_chan; - nveu32_t addr_mask = filter->addr_mask; - nveu32_t src_dest = filter->src_dest; - nveu32_t value = OSI_DISABLE; - nve32_t ret = 0; - - if ((idx > (EQOS_MAX_MAC_ADDRESS_FILTER - 0x1U)) || - (dma_chan >= OSI_EQOS_MAX_NUM_CHANS)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid MAC filter index or channel number\n", - 0ULL); - return -1; - } - - /* read current value at index preserve DCS current value */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_ADDRH((idx))); - - /* High address reset DCS and AE bits*/ - if ((filter->oper_mode & OSI_OPER_ADDR_DEL) != OSI_NONE) { - eqos_l2_filter_delete(osi_core, &value, idx, dma_routing_enable, - dma_chan); - return 0; - } - - ret = eqos_update_mac_addr_helper(osi_core, &value, idx, dma_chan, - addr_mask, src_dest); - /* Check return value from helper code */ - if (ret == -1) { - return ret; - } - - /* Update AE bit if OSI_OPER_ADDR_UPDATE is set */ - if ((filter->oper_mode & OSI_OPER_ADDR_UPDATE) == - OSI_OPER_ADDR_UPDATE) { - value |= EQOS_MAC_ADDRH_AE; - } - - /* Setting Source/Destination Address match valid for 1 to 32 index */ - if (((idx > 0U) && (idx < EQOS_MAX_MAC_ADDR_REG)) && - (src_dest <= OSI_SA_MATCH)) { - value = (value | ((src_dest << EQOS_MAC_ADDRH_SA_SHIFT) & - EQOS_MAC_ADDRH_SA)); - } - - osi_writela(osi_core, ((nveu32_t)filter->mac_address[4] | - ((nveu32_t)filter->mac_address[5] << 8) | value), - (nveu8_t *)osi_core->base + EQOS_MAC_ADDRH((idx))); - - osi_writela(osi_core, ((nveu32_t)filter->mac_address[0] | - ((nveu32_t)filter->mac_address[1] << 8) | - ((nveu32_t)filter->mac_address[2] << 16) | - ((nveu32_t)filter->mac_address[3] << 24)), - (nveu8_t *)osi_core->base + EQOS_MAC_ADDRL((idx))); - - return ret; -} - -/** - * @brief eqos_config_ptp_offload - Enable/Disable PTP offload - * - * Algorithm: Based on input argument, update PTO and TSCR registers. - * Update ptp_filter for TSCR register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] pto_config: The PTP Offload configuration from function - * driver. - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) configure_ptp() should be called after this API - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_ptp_offload(struct osi_core_priv_data *osi_core, - struct osi_pto_config *const pto_config) -{ - unsigned char *addr = (unsigned char *)osi_core->base; - int ret = 0; - unsigned int value = 0x0U; - unsigned int ptc_value = 0x0U; - unsigned int port_id = 0x0U; - - /* Read MAC TCR */ - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_TCR); - /* clear old configuration */ - value &= ~(EQOS_MAC_TCR_TSENMACADDR | OSI_MAC_TCR_SNAPTYPSEL_3 | - OSI_MAC_TCR_TSMASTERENA | OSI_MAC_TCR_TSEVENTENA | - OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR | OSI_MAC_TCR_TSVER2ENA | - OSI_MAC_TCR_TSIPENA); - - /** Handle PTO disable */ - if (pto_config->en_dis == OSI_DISABLE) { - osi_core->ptp_config.ptp_filter = value; - osi_writela(osi_core, ptc_value, addr + EQOS_MAC_PTO_CR); - eqos_core_safety_writel(osi_core, value, addr + - EQOS_MAC_TCR, EQOS_MAC_TCR_IDX); - osi_writela(osi_core, OSI_NONE, addr + EQOS_MAC_PIDR0); - osi_writela(osi_core, OSI_NONE, addr + EQOS_MAC_PIDR1); - osi_writela(osi_core, OSI_NONE, addr + EQOS_MAC_PIDR2); - return 0; - } - - /** Handle PTO enable */ - /* Set PTOEN bit */ - ptc_value |= EQOS_MAC_PTO_CR_PTOEN; - ptc_value |= ((pto_config->domain_num << EQOS_MAC_PTO_CR_DN_SHIFT) - & EQOS_MAC_PTO_CR_DN); - /* Set TSCR register flag */ - value |= (OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR | OSI_MAC_TCR_TSVER2ENA | - OSI_MAC_TCR_TSIPENA); - - if (pto_config->snap_type > 0U) { - /* Set APDREQEN bit if snap_type > 0 */ - ptc_value |= EQOS_MAC_PTO_CR_APDREQEN; - } - - /* Set SNAPTYPSEL for Taking Snapshots mode */ - value |= ((pto_config->snap_type << EQOS_MAC_TCR_SNAPTYPSEL_SHIFT) & - OSI_MAC_TCR_SNAPTYPSEL_3); - - /* Set/Reset TSMSTRENA bit for Master/Slave */ - if (pto_config->master == OSI_ENABLE) { - /* Set TSMSTRENA bit for master */ - value |= OSI_MAC_TCR_TSMASTERENA; - if (pto_config->snap_type != OSI_PTP_SNAP_P2P) { - /* Set ASYNCEN bit on PTO Control Register */ - ptc_value |= EQOS_MAC_PTO_CR_ASYNCEN; - } - } else { - /* Reset TSMSTRENA bit for slave */ - value &= ~OSI_MAC_TCR_TSMASTERENA; - } - - /* Set/Reset TSENMACADDR bit for UC/MC MAC */ - if (pto_config->mc_uc == OSI_ENABLE) { - /* Set TSENMACADDR bit for MC/UC MAC PTP filter */ - value |= EQOS_MAC_TCR_TSENMACADDR; - } else { - /* Reset TSENMACADDR bit */ - value &= ~EQOS_MAC_TCR_TSENMACADDR; - } - - /* Set TSEVENTENA bit for PTP events */ - value |= OSI_MAC_TCR_TSEVENTENA; - osi_core->ptp_config.ptp_filter = value; - /** Write PTO_CR and TCR registers */ - osi_writela(osi_core, ptc_value, addr + EQOS_MAC_PTO_CR); - eqos_core_safety_writel(osi_core, value, addr + EQOS_MAC_TCR, - EQOS_MAC_TCR_IDX); - /* Port ID for PTP offload packet created */ - port_id = pto_config->portid & EQOS_MAC_PIDR_PID_MASK; - osi_writela(osi_core, port_id, addr + EQOS_MAC_PIDR0); - osi_writela(osi_core, OSI_NONE, addr + EQOS_MAC_PIDR1); - osi_writela(osi_core, OSI_NONE, addr + EQOS_MAC_PIDR2); - - return ret; -} - -/** - * @brief eqos_config_l3_l4_filter_enable - register write to enable L3/L4 - * filters. - * - * @note - * Algorithm: - * - This routine to update filter_enb_dis value in IP filter enable register. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in] osi_core: OSI core private data. - * @param[in] filter_enb_dis: enable/disable - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_l3_l4_filter_enable( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_enb_dis) -{ - nveu32_t value = 0U; - void *base = osi_core->base; - value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_PFR); - value &= ~(EQOS_MAC_PFR_IPFE); - value |= ((filter_enb_dis << EQOS_MAC_PFR_IPFE_SHIFT) & - EQOS_MAC_PFR_IPFE); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)base + EQOS_MAC_PFR, - EQOS_MAC_PFR_IDX); - - return 0; -} - -/** - * @brief eqos_update_ip4_addr - configure register for IPV4 address filtering - * - * @note - * Algorithm: - * - Validate addr for null, filter_no for max value and return -1 on failure. - * - Update IPv4 source/destination address for L3 layer filtering. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details. - * @param[in] addr: ipv4 address. Refer #osi_l3_l4_filter->ip4_addr for details. - * @param[in] src_dst_addr_match: Refer #osi_l3_l4_filter->src_dst_addr_match for details. - * - * @pre 1) MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_update_ip4_addr(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu8_t addr[], - const nveu32_t src_dst_addr_match) -{ - void *base = osi_core->base; - nveu32_t value = 0U; - nveu32_t temp = 0U; - - if (addr == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", 0ULL); - return -1; - } - - if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); - return -1; - } - - value = addr[3]; - temp = (nveu32_t)addr[2] << 8; - value |= temp; - temp = (nveu32_t)addr[1] << 16; - value |= temp; - temp = (nveu32_t)addr[0] << 24; - value |= temp; - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD0R(filter_no)); - } else { - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD1R(filter_no)); - } - - return 0; -} - -/** - * @brief eqos_update_ip6_addr - add ipv6 address in register - * - * @note - * Algorithm: - * - Validate addr for null, filter_no for max value and return -1 on failure. - * - Update IPv6 source/destination address for L3 layer filtering. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details. - * @param[in] addr: ipv4 address. Refer #osi_l3_l4_filter->ip6_addr for details. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_update_ip6_addr(struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t addr[]) -{ - void *base = osi_core->base; - nveu32_t value = 0U; - nveu32_t temp = 0U; - - if (addr == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", 0ULL); - return -1; - } - - if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); - return -1; - } - - /* update Bits[31:0] of 128-bit IP addr */ - value = addr[7]; - temp = (nveu32_t)addr[6] << 16; - value |= temp; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD0R(filter_no)); - /* update Bits[63:32] of 128-bit IP addr */ - value = addr[5]; - temp = (nveu32_t)addr[4] << 16; - value |= temp; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD1R(filter_no)); - /* update Bits[95:64] of 128-bit IP addr */ - value = addr[3]; - temp = (nveu32_t)addr[2] << 16; - value |= temp; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD2R(filter_no)); - /* update Bits[127:96] of 128-bit IP addr */ - value = addr[1]; - temp = (nveu32_t)addr[0] << 16; - value |= temp; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3_AD3R(filter_no)); - - return 0; -} - -/** - * @brief eqos_update_l4_port_no -program source port no - * - * @note - * Algorithm: - * - Validate filter_no for max value and return -1 on failure. - * - Update port_no based on src_dst_port_match to confiure L4 layer filtering. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in] osi_core: OSI core private data structure. Used param base. - * @param[in] filter_no: filter index. Refer #osi_l3_l4_filter->filter_no for details. - * @param[in] port_no: ipv4 address. Refer #osi_l3_l4_filter->port_no for details. - * @param[in] src_dst_port_match: Refer #osi_l3_l4_filter->src_dst_port_match for details. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - DCS bits should be enabled in RXQ to DMA mapping register - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_update_l4_port_no( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu16_t port_no, - const nveu32_t src_dst_port_match) -{ - void *base = osi_core->base; - nveu32_t value = 0U; - nveu32_t temp = 0U; - - if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); - return -1; - } - - value = osi_readla(osi_core, - (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); - if (src_dst_port_match == OSI_SOURCE_MATCH) { - value &= ~EQOS_MAC_L4_SP_MASK; - value |= ((nveu32_t)port_no & EQOS_MAC_L4_SP_MASK); - } else { - value &= ~EQOS_MAC_L4_DP_MASK; - temp = port_no; - value |= ((temp << EQOS_MAC_L4_DP_SHIFT) & EQOS_MAC_L4_DP_MASK); - } - osi_writela(osi_core, value, - (nveu8_t *)base + EQOS_MAC_L4_ADR(filter_no)); - - return 0; -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief eqos_set_dcs - check and update dma routing register - * - * @note - * Algorithm: - * - Check for request for DCS_enable as well as validate chan - * number and dcs_enable is set. After validation, this sequence is used - * to configure L3((IPv4/IPv6) filters for address matching. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] value: nveu32_t value for caller - * @param[in] dma_routing_enable: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - DCS bit of RxQ should be enabled for dynamic channel selection - * in filter support - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - *@return updated nveu32_t value - */ -static inline nveu32_t eqos_set_dcs( - struct osi_core_priv_data *const osi_core, - nveu32_t value, - nveu32_t dma_routing_enable, - nveu32_t dma_chan) -{ - nveu32_t t_val = value; - - if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < - OSI_EQOS_MAX_NUM_CHANS) && (osi_core->dcs_en == - OSI_ENABLE)) { - t_val |= ((dma_routing_enable << - EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT) & - EQOS_MAC_L3L4_CTR_DMCHEN0); - t_val |= ((dma_chan << - EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT) & - EQOS_MAC_L3L4_CTR_DMCHN0); - } - - return t_val; -} - -/** - * @brief eqos_helper_l3l4_bitmask - helper function to set L3L4 - * bitmask. - * - * @note - * Algorithm: - * - set bit corresponding to L3l4 filter index - * - * @param[out] bitmask: bit mask OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] value: 0 - disable otherwise - l3/l4 filter enabled - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - */ -static inline void eqos_helper_l3l4_bitmask(nveu32_t *bitmask, - nveu32_t filter_no, - nveu32_t value) -{ - nveu32_t temp; - - /* Set bit mask for index */ - temp = OSI_ENABLE; - temp = temp << filter_no; - /* check against all bit fields for L3L4 filter enable */ - if ((value & EQOS_MAC_L3L4_CTRL_ALL) != OSI_DISABLE) { - *bitmask |= temp; - } else { - *bitmask &= ~temp; - } -} -/** \endcond */ - -/** - * @brief eqos_config_l3_filters - config L3 filters. - * - * @note - * Algorithm: - * - Validate filter_no for maximum and hannel number if dma_routing_enable - * is OSI_ENABLE and reitrn -1 if fails. - * - Configure L3 filter register based on all arguments(except for osi_core and dma_routing_enable) - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in, out] osi_core: OSI core private data structure. Used param is base. - * @param[in] filter_no: filter index. Max EQOS_MAX_L3_L4_FILTER - 1. - * @param[in] enb_dis: OSI_ENABLE - enable otherwise - disable L3 filter. - * @param[in] ipv4_ipv6_match: OSI_IPV6_MATCH - IPv6, otherwise - IPv4. - * @param[in] src_dst_addr_match: OSI_SOURCE_MATCH - source, otherwise - destination. - * @param[in] perfect_inverse_match: normal match(0) or inverse map(1). - * @param[in] dma_routing_enable: Valid value OSI_ENABLE, invalid otherwise. - * @param[in] dma_chan: dma channel for routing based on filter. Max OSI_EQOS_MAX_NUM_CHANS-1. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - DCS bit of RxQ should be enabled for dynamic channel selection - * in filter support - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_l3_filters( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu32_t enb_dis, - const nveu32_t ipv4_ipv6_match, - const nveu32_t src_dst_addr_match, - const nveu32_t perfect_inverse_match, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan) -{ - nveu32_t value = 0U; - void *base = osi_core->base; - - if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); - return -1; - } - - if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", (nveul64_t)dma_chan); - return -1; - } - - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3L4_CTR_L3PEN0; - value |= (ipv4_ipv6_match & EQOS_MAC_L3L4_CTR_L3PEN0); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - - /* For IPv6 either SA/DA can be checked not both */ - if (ipv4_ipv6_match == OSI_IPV6_MATCH) { - if (enb_dis == OSI_ENABLE) { - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - /* Enable L3 filters for IPv6 SOURCE addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L3SAI_SHIFT)) & - ((EQOS_MAC_L3L4_CTR_L3SAM0 | - EQOS_MAC_L3L4_CTR_L3SAIM0))); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - - } else { - /* Enable L3 filters for IPv6 DESTINATION addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP6_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L3DAI_SHIFT)) & - ((EQOS_MAC_L3L4_CTR_L3DAM0 | - EQOS_MAC_L3L4_CTR_L3DAIM0))); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } else { - /* Disable L3 filters for IPv6 SOURCE/DESTINATION addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~(EQOS_MAC_L3_IP6_CTRL_CLEAR | - EQOS_MAC_L3L4_CTR_L3PEN0); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } else { - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - if (enb_dis == OSI_ENABLE) { - /* Enable L3 filters for IPv4 SOURCE addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L3SAM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L3SAI_SHIFT)) & - ((EQOS_MAC_L3L4_CTR_L3SAM0 | - EQOS_MAC_L3L4_CTR_L3SAIM0))); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } else { - /* Disable L3 filters for IPv4 SOURCE addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP4_SA_CTRL_CLEAR; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } else { - if (enb_dis == OSI_ENABLE) { - /* Enable L3 filters for IPv4 DESTINATION addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L3DAM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L3DAI_SHIFT)) & - ((EQOS_MAC_L3L4_CTR_L3DAM0 | - EQOS_MAC_L3L4_CTR_L3DAIM0))); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } else { - /* Disable L3 filters for IPv4 DESTINATION addr - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3_IP4_DA_CTRL_CLEAR; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } - } - - /* Set bit corresponding to filter index if value is non-zero */ - eqos_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, - filter_no, value); - - return 0; -} - -/** - * @brief eqos_config_l4_filters - Config L4 filters. - * - * @note - * Algorithm: - * - Validate filter_no for maximum and hannel number if dma_routing_enable - * is OSI_ENABLE and reitrn -1 if fails. - * - Configure L4 filter register based on all arguments(except for osi_core and dma_routing_enable) - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_019 - * - * @param[in, out] osi_core: OSI core private data structure. Used param is base. - * @param[in] filter_no: filter index. Max EQOS_MAX_L3_L4_FILTER - 1. - * @param[in] enb_dis: OSI_ENABLE - enable, otherwise - disable L4 filter - * @param[in] tcp_udp_match: 1 - udp, 0 - tcp - * @param[in] src_dst_port_match: OSI_SOURCE_MATCH - source port, otherwise - dest port - * @param[in] perfect_inverse_match: normal match(0) or inverse map(1) - * @param[in] dma_routing_enable: Valid value OSI_ENABLE, invalid otherwise. - * @param[in] dma_chan: dma channel for routing based on filter. Max OSI_EQOS_MAX_NUM_CHANS-1. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_l4_filters( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_no, - const nveu32_t enb_dis, - const nveu32_t tcp_udp_match, - const nveu32_t src_dst_port_match, - const nveu32_t perfect_inverse_match, - const nveu32_t dma_routing_enable, - const nveu32_t dma_chan) -{ - void *base = osi_core->base; - nveu32_t value = 0U; - - if (filter_no > (EQOS_MAX_L3_L4_FILTER - 0x1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (nveul64_t)filter_no); - return -1; - } - - if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > (OSI_EQOS_MAX_NUM_CHANS - 1U))) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", (nveu32_t)dma_chan); - return -1; - } - - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L3L4_CTR_L4PEN0; - value |= ((tcp_udp_match << EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT) - & EQOS_MAC_L3L4_CTR_L4PEN0); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - - if (src_dst_port_match == OSI_SOURCE_MATCH) { - if (enb_dis == OSI_ENABLE) { - /* Enable L4 filters for SOURCE Port No matching */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L4SPM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L4SPI_SHIFT)) & - (EQOS_MAC_L3L4_CTR_L4SPM0 | - EQOS_MAC_L3L4_CTR_L4SPIM0)); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } else { - /* Disable L4 filters for SOURCE Port No matching */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L4_SP_CTRL_CLEAR; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } else { - if (enb_dis == OSI_ENABLE) { - /* Enable L4 filters for DESTINATION port No - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; - value |= ((EQOS_MAC_L3L4_CTR_L4DPM0 | - (perfect_inverse_match << - EQOS_MAC_L3L4_CTR_L4DPI_SHIFT)) & - (EQOS_MAC_L3L4_CTR_L4DPM0 | - EQOS_MAC_L3L4_CTR_L4DPIM0)); - value |= eqos_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } else { - /* Disable L4 filters for DESTINATION port No - * matching - */ - value = osi_readla(osi_core, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - value &= ~EQOS_MAC_L4_DP_CTRL_CLEAR; - osi_writela(osi_core, value, (nveu8_t *)base + - EQOS_MAC_L3L4_CTR(filter_no)); - } - } - /* Set bit corresponding to filter index if value is non-zero */ - eqos_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, - filter_no, value); - - return 0; -} - -/** - * @brief eqos_poll_for_tsinit_complete - Poll for time stamp init complete - * - * @note - * Algorithm: - * - Read TSINIT value from MAC TCR register until it is equal to zero. - * - Max loop count of 1000 with 1 ms delay between iterations. - * - SWUD_ID: ETHERNET_NVETHERNETRM_005_1 - * - * @param[in] osi_core: OSI core private data structure. Used param is base, osd_ops.udelay. - * @param[in, out] mac_tcr: Address to store time stamp control register read - * value - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t eqos_poll_for_tsinit_complete( - struct osi_core_priv_data *const osi_core, - nveu32_t *mac_tcr) -{ - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nve32_t cond = COND_NOT_MET; - - /* Wait for previous(if any) Initialize Timestamp value - * update to complete - */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_tsinit: timeout\n", 0ULL); - return -1; - } - /* Read and Check TSINIT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_TCR); - if ((*mac_tcr & EQOS_MAC_TCR_TSINIT) == 0U) { - cond = COND_MET; - } - - count++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return 0; -} - -/** - * @brief eqos_set_systime_to_mac - Set system time - * - * @note - * Algorithm: - * - Updates system time (seconds and nano seconds) in hardware registers. - * - Calls eqos_poll_for_tsinit_complete() before and after setting time. - * - return -1 if API fails. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_005 - * - * @param[in] osi_core: OSI core private data structure. Used param is base. - * @param[in] sec: Seconds to be configured - * @param[in] nsec: Nano Seconds to be configured - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_set_systime_to_mac( - struct osi_core_priv_data *const osi_core, - const nveu32_t sec, - const nveu32_t nsec) -{ - void *addr = osi_core->base; - nveu32_t mac_tcr; - nve32_t ret; - - /* To be sure previous write was flushed (if Any) */ - ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (nveu8_t *)addr + EQOS_MAC_STSUR); - - /* write nano seconds value to MAC_System_Time_Nanoseconds_Update - * register - */ - osi_writela(osi_core, nsec, (nveu8_t *)addr + EQOS_MAC_STNSUR); - - /* issue command to update the configured secs and nsecs values */ - mac_tcr |= EQOS_MAC_TCR_TSINIT; - eqos_core_safety_writel(osi_core, mac_tcr, - (nveu8_t *)addr + EQOS_MAC_TCR, - EQOS_MAC_TCR_IDX); - - ret = eqos_poll_for_tsinit_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** - * @brief eqos_poll_for_addend_complete - Poll for addend value write complete - * - * @note - * Algorithm: - * - Read TSADDREG value from MAC TCR register until it is equal to zero. - * - Max loop count of 1000 with 1 ms delay between iterations. - * - SWUD_ID: ETHERNET_NVETHERNETRM_023_1 - * - * @param[in] osi_core: OSI core private data structure. Used param is base, osd_ops.udelay. - * @param[in, out] mac_tcr: Address to store time stamp control register read - * value - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t eqos_poll_for_addend_complete( - struct osi_core_priv_data *const osi_core, - nveu32_t *mac_tcr) -{ - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nve32_t cond = COND_NOT_MET; - - /* Wait for previous(if any) addend value update to complete */ - /* Poll */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_addend: timeout\n", 0ULL); - return -1; - } - /* Read and Check TSADDREG in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_TCR); - if ((*mac_tcr & EQOS_MAC_TCR_TSADDREG) == 0U) { - cond = COND_MET; - } - - count++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return 0; -} - -/** - * @brief eqos_config_addend - Configure addend - * - * @note - * Algorithm: - * - Updates the Addend value in HW register - * - Calls eqos_poll_for_addend_complete() before and after setting time. - * - return -1 if API fails. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_023 - * - * @param[in] osi_core: OSI core private data structure. Used param is base. - * @param[in] addend: Addend value to be configured - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_addend(struct osi_core_priv_data *const osi_core, - const nveu32_t addend) -{ - nveu32_t mac_tcr; - nve32_t ret; - - /* To be sure previous write was flushed (if Any) */ - ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - /* write addend value to MAC_Timestamp_Addend register */ - eqos_core_safety_writel(osi_core, addend, - (nveu8_t *)osi_core->base + EQOS_MAC_TAR, - EQOS_MAC_TAR_IDX); - - /* issue command to update the configured addend value */ - mac_tcr |= EQOS_MAC_TCR_TSADDREG; - eqos_core_safety_writel(osi_core, mac_tcr, - (nveu8_t *)osi_core->base + EQOS_MAC_TCR, - EQOS_MAC_TCR_IDX); - - ret = eqos_poll_for_addend_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** - * @brief eqos_poll_for_update_ts_complete - Poll for update time stamp - * - * @note - * Algorithm: - * - Read time stamp update value from TCR register until it is - * equal to zero. - * - Max loop count of 1000 with 1 ms delay between iterations. - * - SWUD_ID: ETHERNET_NVETHERNETRM_022_1 - * - * @param[in] osi_core: OSI core private data structure. Used param is base, osd_ops.udelay. - * @param[in, out] mac_tcr: Address to store time stamp control register read - * value - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t eqos_poll_for_update_ts_complete( - struct osi_core_priv_data *const osi_core, - nveu32_t *mac_tcr) -{ - nveu32_t retry = RETRY_COUNT; - nveu32_t count; - nve32_t cond = COND_NOT_MET; - - /* Wait for previous(if any) time stamp value update to complete */ - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "poll_for_update_ts: timeout\n", 0ULL); - return -1; - } - /* Read and Check TSUPDT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_TCR); - if ((*mac_tcr & EQOS_MAC_TCR_TSUPDT) == 0U) { - cond = COND_MET; - } - - count++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return 0; - -} - -/** - * @brief eqos_adjust_mactime - Adjust MAC time with system time - * - * @note - * Algorithm: - * - Update MAC time with system time based on input arguments(except osi_core) - * - Calls eqos_poll_for_update_ts_complete() before and after setting time. - * - return -1 if API fails. - * - Refer to EQOS column of <> for API details. - * - TraceID:ETHERNET_NVETHERNETRM_022 - * - * @param[in] osi_core: OSI core private data structure. Used param is base. - * @param[in] sec: Seconds to be configured - * @param[in] nsec: Nano seconds to be configured - * @param[in] add_sub: To decide on add/sub with system time - * @param[in] one_nsec_accuracy: One nano second accuracy - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->ptp_config.one_nsec_accuracy need to be set to 1 - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_adjust_mactime(struct osi_core_priv_data *const osi_core, - const nveu32_t sec, const nveu32_t nsec, - const nveu32_t add_sub, - const nveu32_t one_nsec_accuracy) -{ - void *addr = osi_core->base; - nveu32_t mac_tcr; - nveu32_t value = 0; - nveul64_t temp = 0; - nveu32_t sec1 = sec; - nveu32_t nsec1 = nsec; - nve32_t ret; - - ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - if (add_sub != 0U) { - /* If the new sec value needs to be subtracted with - * the system time, then MAC_STSUR reg should be - * programmed with (2^32 – ) - */ - temp = (TWO_POWER_32 - sec1); - if (temp < UINT_MAX) { - sec1 = (nveu32_t)temp; - } else { - /* do nothing here */ - } - - /* If the new nsec value need to be subtracted with - * the system time, then MAC_STNSUR.TSSS field should be - * programmed with, (10^9 - ) if - * MAC_TCR.TSCTRLSSR is set or - * (2^32 - if MAC_TCR.TSCTRLSSR is reset) - */ - if (one_nsec_accuracy == OSI_ENABLE) { - if (nsec1 < UINT_MAX) { - nsec1 = (TEN_POWER_9 - nsec1); - } - } else { - if (nsec1 < UINT_MAX) { - nsec1 = (TWO_POWER_31 - nsec1); - } - } - } - - /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec1, (nveu8_t *)addr + EQOS_MAC_STSUR); - - /* write nano seconds value and add_sub to - * MAC_System_Time_Nanoseconds_Update register - */ - value |= nsec1; - value |= add_sub << EQOS_MAC_STNSUR_ADDSUB_SHIFT; - osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_STNSUR); - - /* issue command to initialize system time with the value - * specified in MAC_STSUR and MAC_STNSUR - */ - mac_tcr |= EQOS_MAC_TCR_TSUPDT; - eqos_core_safety_writel(osi_core, mac_tcr, - (nveu8_t *)addr + EQOS_MAC_TCR, - EQOS_MAC_TCR_IDX); - - ret = eqos_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief eqos_config_tscr - Configure Time Stamp Register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] ptp_filter: PTP rx filter parameters - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_config_tscr(struct osi_core_priv_data *const osi_core, - const nveu32_t ptp_filter) -{ - void *addr = osi_core->base; - struct core_local *l_core = (struct core_local *)osi_core; - nveu32_t mac_tcr = 0U, i = 0U, temp = 0U; - nveu32_t value = 0x0U; - - if (ptp_filter != OSI_DISABLE) { - mac_tcr = (OSI_MAC_TCR_TSENA | - OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR); - - for (i = 0U; i < 32U; i++) { - temp = ptp_filter & OSI_BIT(i); - - switch (temp) { - case OSI_MAC_TCR_SNAPTYPSEL_1: - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_1; - break; - case OSI_MAC_TCR_SNAPTYPSEL_2: - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_2; - break; - case OSI_MAC_TCR_TSIPV4ENA: - mac_tcr |= OSI_MAC_TCR_TSIPV4ENA; - break; - case OSI_MAC_TCR_TSIPV6ENA: - mac_tcr |= OSI_MAC_TCR_TSIPV6ENA; - break; - case OSI_MAC_TCR_TSEVENTENA: - mac_tcr |= OSI_MAC_TCR_TSEVENTENA; - break; - case OSI_MAC_TCR_TSMASTERENA: - mac_tcr |= OSI_MAC_TCR_TSMASTERENA; - break; - case OSI_MAC_TCR_TSVER2ENA: - mac_tcr |= OSI_MAC_TCR_TSVER2ENA; - break; - case OSI_MAC_TCR_TSIPENA: - mac_tcr |= OSI_MAC_TCR_TSIPENA; - break; - case OSI_MAC_TCR_AV8021ASMEN: - mac_tcr |= OSI_MAC_TCR_AV8021ASMEN; - break; - case OSI_MAC_TCR_TSENALL: - mac_tcr |= OSI_MAC_TCR_TSENALL; - break; - case OSI_MAC_TCR_CSC: - mac_tcr |= OSI_MAC_TCR_CSC; - break; - default: - /* To avoid MISRA violation */ - mac_tcr |= mac_tcr; - break; - } - } - } else { - /* Disabling the MAC time stamping */ - mac_tcr = OSI_DISABLE; - } - - eqos_core_safety_writel(osi_core, mac_tcr, - (nveu8_t *)addr + EQOS_MAC_TCR, - EQOS_MAC_TCR_IDX); - value = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_PPS_CTL); - value &= ~EQOS_MAC_PPS_CTL_PPSCTRL0; - if (l_core->pps_freq == OSI_ENABLE) { - value |= OSI_ENABLE; - } - osi_writela(osi_core, value, (nveu8_t *)addr + EQOS_MAC_PPS_CTL); -} -/** \endcond */ - -/** - * @brief eqos_config_ptp_rxq - To config PTP RX packets queue - * - * Algorithm: This function is used to program the PTP RX packets queue. - * - * @param[in] osi_core: OSI core private data. - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_config_ptp_rxq(struct osi_core_priv_data *osi_core, - const unsigned int rxq_idx, - const unsigned int enable) -{ - unsigned char *base = osi_core->base; - unsigned int value = OSI_NONE; - unsigned int i = 0U; - - /* Validate the RX queue index argment */ - if (rxq_idx >= OSI_EQOS_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid PTP RX queue index\n", - rxq_idx); - return -1; - } - /* Check MAC version */ - if (osi_core->mac_ver <= OSI_EQOS_MAC_5_00) { - /* MAC 4_10 and 5 doesn't have PTP RX Queue route support */ - return 0; - } - - /* Validate enable argument */ - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid enable input\n", - enable); - return -1; - } - - /* Validate PTP RX queue enable */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - if (osi_core->mtl_queues[i] == rxq_idx) { - /* Given PTP RX queue is enabled */ - break; - } - } - - if (i == osi_core->num_mtl_queues) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "PTP RX queue not enabled\n", - rxq_idx); - return -1; - } - - /* Read MAC_RxQ_Ctrl1 */ - value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_RQC1R); - if (enable == OSI_DISABLE) { - /** Reset OMCBCQ bit to disable over-riding the MCBC Queue - * priority for the PTP RX queue. - */ - value &= ~EQOS_MAC_RQC1R_OMCBCQ; - - } else { - /* Program PTPQ with ptp_rxq */ - osi_core->ptp_config.ptp_rx_queue = rxq_idx; - value &= ~EQOS_MAC_RQC1R_PTPQ; - value |= (rxq_idx << EQOS_MAC_RQC1R_PTPQ_SHIFT); - /* Reset TPQC before setting TPQC0 */ - value &= ~EQOS_MAC_RQC1R_TPQC; - /** Set TPQC to 0x1 for VLAN Tagged PTP over - * ethernet packets are routed to Rx Queue specified - * by PTPQ field - **/ - value |= EQOS_MAC_RQC1R_TPQC0; - /** Set OMCBCQ bit to enable over-riding the MCBC Queue - * priority for the PTP RX queue. - */ - value |= EQOS_MAC_RQC1R_OMCBCQ; - } - /* Write MAC_RxQ_Ctrl1 */ - osi_writela(osi_core, value, base + EQOS_MAC_RQC1R); - - return 0; -} - -/** - * @brief eqos_config_ssir - Configure SSIR register - * - * @note - * Algorithm: - * - Calculate SSIR - * - For Coarse method(EQOS_MAC_TCR_TSCFUPDT not set in TCR register), ((1/ptp_clock) * 1000000000). - * - For fine correction use predeined value based on MAC version OSI_PTP_SSINC_16 if MAC version - * less than OSI_EQOS_MAC_4_10 and OSI_PTP_SSINC_4 if otherwise. - * - If EQOS_MAC_TCR_TSCTRLSSR bit not set in TCR register, set accurasy to 0.465ns. - * - i.e new val = val * 1000/465; - * - Program the calculated value to EQOS_MAC_SSIR register - * - Refer to EQOS column of <> for API details. - * - SWUD_ID: ETHERNET_NVETHERNETRM_021_1 - * - * @param[in] osi_core: OSI core private data structure. Used param is base, mac_ver. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_config_ssir(struct osi_core_priv_data *const osi_core, - const unsigned int ptp_clock) -{ - nveul64_t val; - nveu32_t mac_tcr; - void *addr = osi_core->base; - - mac_tcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_TCR); - - if ((mac_tcr & EQOS_MAC_TCR_TSCFUPDT) == EQOS_MAC_TCR_TSCFUPDT) { - if (osi_core->mac_ver <= OSI_EQOS_MAC_4_10) { - val = OSI_PTP_SSINC_16; - } else if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { - val = OSI_PTP_SSINC_6; - } else { - val = OSI_PTP_SSINC_4; - } - } else { - /* convert the PTP required clock frequency to nano second for - * COARSE correction. - * Formula: ((1/ptp_clock) * 1000000000) - */ - val = ((1U * OSI_NSEC_PER_SEC) / ptp_clock); - } - - /* 0.465ns accurecy */ - if ((mac_tcr & EQOS_MAC_TCR_TSCTRLSSR) == 0U) { - if (val < UINT_MAX) { - val = (val * 1000U) / 465U; - } - } - - val |= val << EQOS_MAC_SSIR_SSINC_SHIFT; - /* update Sub-second Increment Value */ - if (val < UINT_MAX) { - eqos_core_safety_writel(osi_core, (nveu32_t)val, - (nveu8_t *)addr + EQOS_MAC_SSIR, - EQOS_MAC_SSIR_IDX); - } -} - -/** - * @brief eqos_core_deinit - EQOS MAC core deinitialization - * - * @note - * Algorithm: - * - This function calls eqos_stop_mac() - * - TraceId:ETHERNET_NVETHERNETRM_007 - * - * @param[in] osi_core: OSI core private data structure. Used param is base. - * - * @pre Required clks and resets has to be enabled - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - */ -static void eqos_core_deinit(struct osi_core_priv_data *const osi_core) -{ - /* Stop the MAC by disabling both MAC Tx and Rx */ - eqos_stop_mac(osi_core); -} - -/** - * @brief eqos_hw_est_write - indirect write the GCL to Software own list - * (SWOL) - * - * @param[in] base: MAC base IOVA address. - * @param[in] addr_val: Address offset for indirect write. - * @param[in] data: Data to be written at offset. - * @param[in] gcla: Gate Control List Address, 0 for ETS register. - * 1 for GCL memory. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_hw_est_write(struct osi_core_priv_data *osi_core, - unsigned int addr_val, - unsigned int data, unsigned int gcla) -{ - void *base = osi_core->base; - int retry = 1000; - unsigned int val = 0x0; - - osi_writela(osi_core, data, (unsigned char *)base + EQOS_MTL_EST_DATA); - - val &= ~EQOS_MTL_EST_ADDR_MASK; - val |= (gcla == 1U) ? 0x0U : EQOS_MTL_EST_GCRR; - val |= EQOS_MTL_EST_SRWO; - val |= addr_val; - osi_writela(osi_core, val, - (unsigned char *)base + EQOS_MTL_EST_GCL_CONTROL); - - while (--retry > 0) { - osi_core->osd_ops.udelay(OSI_DELAY_1US); - val = osi_readla(osi_core, (unsigned char *)base + - EQOS_MTL_EST_GCL_CONTROL); - if ((val & EQOS_MTL_EST_SRWO) == EQOS_MTL_EST_SRWO) { - continue; - } - - break; - } - - if (((val & EQOS_MTL_EST_ERR0) == EQOS_MTL_EST_ERR0) || - (retry <= 0)) { - return -1; - } - - return 0; -} - -/** - * @brief eqos_hw_config_est - Read Setting for GCL from input and update - * registers. - * - * Algorithm: - * 1) Write TER, LLR and EST control register - * 2) Update GCL to sw own GCL (MTL_EST_Status bit SWOL will tell which is - * owned by SW) and store which GCL is in use currently in sw. - * 3) TODO set DBGB and DBGM for debugging - * 4) EST_data and GCRR to 1, update entry sno in ADDR and put data at - * est_gcl_data enable GCL MTL_EST_SSWL and wait for self clear or use - * SWLC in MTL_EST_Status. Please note new GCL will be pushed for each entry. - * 5) Configure btr. Update btr based on current time (current time - * should be updated based on PTP by this time) - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est: EST configuration input argument. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_hw_config_est(struct osi_core_priv_data *osi_core, - struct osi_est_config *est) -{ - void *base = osi_core->base; - unsigned int btr[2] = {0}; - unsigned int val = 0x0; - unsigned int addr = 0x0; - unsigned int i; - int ret = 0; - - if ((osi_core->hw_feature != OSI_NULL) && - (osi_core->hw_feature->est_sel == OSI_DISABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "EST not supported in HW\n", 0ULL); - return -1; - } - - if (est->en_dis == OSI_DISABLE) { - val = osi_readla(osi_core, - (nveu8_t *)base + EQOS_MTL_EST_CONTROL); - val &= ~EQOS_MTL_EST_CONTROL_EEST; - osi_writela(osi_core, val, - (nveu8_t *)base + EQOS_MTL_EST_CONTROL); - return 0; - } - - btr[0] = est->btr[0]; - btr[1] = est->btr[1]; - - if (btr[0] == 0U && btr[1] == 0U) { - common_get_systime_from_mac(osi_core->base, osi_core->mac, - &btr[1], &btr[0]); - } - - if (gcl_validate(osi_core, est, btr, osi_core->mac) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL validation failed\n", 0LL); - return -1; - } - - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_CTR_LOW, est->ctr[0], - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL CTR[0] failed\n", 0LL); - return ret; - } - /* check for est->ctr[i] not more than FF, TODO as per hw config - * parameter we can have max 0x3 as this value in sec */ - est->ctr[1] &= EQOS_MTL_EST_CTR_HIGH_MAX; - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_CTR_HIGH, est->ctr[1], - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL CTR[1] failed\n", 0LL); - return ret; - } - - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_TER, est->ter, - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL TER failed\n", 0LL); - return ret; - } - - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_LLR, est->llr, - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL LLR failed\n", 0LL); - return ret; - } - - /* Write GCL table */ - for (i = 0U; i < est->llr; i++) { - addr = i; - addr = addr << EQOS_MTL_EST_ADDR_SHIFT; - addr &= EQOS_MTL_EST_ADDR_MASK; - ret = eqos_hw_est_write(osi_core, addr, est->gcl[i], - OSI_ENABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL enties write failed\n", - (unsigned long long)i); - return ret; - } - } - - /* Write parameters */ - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_BTR_LOW, - btr[0] + est->btr_offset[0], OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL BTR[0] failed\n", - (unsigned long long)(btr[0] + - est->btr_offset[0])); - return ret; - } - - ret = eqos_hw_est_write(osi_core, EQOS_MTL_EST_BTR_HIGH, - btr[1] + est->btr_offset[1], OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL BTR[1] failed\n", - (unsigned long long)(btr[1] + - est->btr_offset[1])); - return ret; - } - - val = osi_readla(osi_core, (unsigned char *) - base + EQOS_MTL_EST_CONTROL); - /* Store table */ - val |= EQOS_MTL_EST_CONTROL_SSWL; - val |= EQOS_MTL_EST_CONTROL_EEST; - val |= EQOS_MTL_EST_CONTROL_QHLBF; - osi_writela(osi_core, val, (nveu8_t *)base + EQOS_MTL_EST_CONTROL); - - return ret; -} - -/** - * @brief eqos_hw_config_fep - Read Setting for preemption and express for TC - * and update registers. - * - * Algorithm: - * 1) Check for TC enable and TC has masked for setting to preemptable. - * 2) update FPE control status register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] fpe: FPE configuration input argument. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_hw_config_fpe(struct osi_core_priv_data *osi_core, - struct osi_fpe_config *fpe) -{ - unsigned int i = 0U; - unsigned int val = 0U; - unsigned int temp = 0U, temp1 = 0U; - unsigned int temp_shift = 0U; - - if ((osi_core->hw_feature != OSI_NULL) && - (osi_core->hw_feature->fpe_sel == OSI_DISABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "FPE not supported in HW\n", 0ULL); - return -1; - } - - osi_core->fpe_ready = OSI_DISABLE; - - - if (((fpe->tx_queue_preemption_enable << EQOS_MTL_FPE_CTS_PEC_SHIFT) & - EQOS_MTL_FPE_CTS_PEC) == OSI_DISABLE) { - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_CTS); - val &= ~EQOS_MTL_FPE_CTS_PEC; - osi_writela(osi_core, val, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_CTS); - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MAC_FPE_CTS); - val &= ~EQOS_MAC_FPE_CTS_EFPE; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - EQOS_MAC_FPE_CTS); - - return 0; - } - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_CTS); - val &= ~EQOS_MTL_FPE_CTS_PEC; - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - /* max 8 bit for this structure fot TC/TXQ. Set the TC for express or - * preemption. Default is express for a TC. DWCXG_NUM_TC = 8 */ - temp = OSI_BIT(i); - if ((fpe->tx_queue_preemption_enable & temp) == temp) { - temp_shift = i; - temp_shift += EQOS_MTL_FPE_CTS_PEC_SHIFT; - /* set queue for preemtable */ - if (temp_shift < EQOS_MTL_FPE_CTS_PEC_MAX_SHIFT) { - temp1 = OSI_ENABLE; - temp1 = temp1 << temp_shift; - val |= temp1; - } else { - /* Do nothing */ - } - } - } - osi_writela(osi_core, val, - (nveu8_t *)osi_core->base + EQOS_MTL_FPE_CTS); - - /* Setting RQ as RxQ 0 is not allowed */ - if (fpe->rq == 0x0U || fpe->rq >= OSI_EQOS_MAX_NUM_CHANS) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "EST init failed due to wrong RQ\n", fpe->rq); - return -1; - } - - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); - val &= ~EQOS_MAC_RQC1R_FPRQ; - temp = fpe->rq; - temp = temp << EQOS_MAC_RQC1R_FPRQ_SHIFT; - temp = (temp & EQOS_MAC_RQC1R_FPRQ); - val |= temp; - /* update RQ in OSI CORE struct */ - osi_core->residual_queue = fpe->rq; - osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MAC_RQC1R); - - /* initiate SVER for SMD-V and SMD-R */ - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_CTS); - val |= EQOS_MAC_FPE_CTS_SVER; - osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MAC_FPE_CTS); - - val = osi_readla(osi_core, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); - val &= ~EQOS_MTL_FPE_ADV_HADV_MASK; - /* (minimum_fragment_size +IPG/EIPG + Preamble) *.8 ~98ns for10G */ - val |= EQOS_MTL_FPE_ADV_HADV_VAL; - osi_writela(osi_core, val, - (unsigned char *)osi_core->base + EQOS_MTL_FPE_ADV); - - return 0; -} - -/** \cond DO_NOT_DOCUMENT */ -/** - * @brief poll_for_mii_idle Query the status of an ongoing DMA transfer - * - * @param[in] osi_core: OSI Core private data structure. - * - * @pre MAC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t poll_for_mii_idle(struct osi_core_priv_data *osi_core) -{ - /* half sec timeout */ - nveu32_t retry = ((RETRY_COUNT) * 50U); - nveu32_t mac_gmiiar; - nveu32_t count; - nve32_t cond = COND_NOT_MET; - - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", 0ULL); - return -1; - } - count++; - - mac_gmiiar = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); - if ((mac_gmiiar & EQOS_MAC_GMII_BUSY) == 0U) { - /* exit loop */ - cond = COND_MET; - } else { - /* wait on GMII Busy set */ - osi_core->osd_ops.udelay(10U); - } - } - - return 0; -} -/** \endcond */ - -/** - * @brief eqos_write_phy_reg - Write to a PHY register through MAC over MDIO bus - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Program data into MAC MDIO data register. - * - Populate required parameters like phy address, phy register etc,, - * in MAC MDIO Address register. write and GMII busy bits needs to be set - * in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. - * - Refer to EQOS column of <> for API details. - * - Traceid:ETHERNET_NVETHERNETRM_002 - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be write to PHY. - * @param[in] phydata: Data to write to a PHY register. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg, - const nveu16_t phydata) -{ - nveu32_t mac_gmiiar; - nveu32_t mac_gmiidr; - nveu32_t devaddr; - nve32_t ret = 0; - - /* Wait for any previous MII read/write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - /* poll_for_mii_idle fail */ - return ret; - } - - /* C45 register access */ - if ((phyreg & OSI_MII_ADDR_C45) == OSI_MII_ADDR_C45) { - /* Write the PHY register address and data into data register */ - mac_gmiidr = (phyreg & EQOS_MDIO_DATA_REG_PHYREG_MASK) << - EQOS_MDIO_DATA_REG_PHYREG_SHIFT; - mac_gmiidr |= phydata; - osi_writela(osi_core, mac_gmiidr, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); - - /* Extract the device address */ - devaddr = (phyreg >> EQOS_MDIO_DATA_REG_DEV_ADDR_SHIFT) & - EQOS_MDIO_DATA_REG_DEV_ADDR_MASK; - - /* Initiate the clause 45 transaction with auto - * generation of address packet - */ - mac_gmiiar = (EQOS_MDIO_PHY_REG_C45E | - ((phyaddr) << EQOS_MDIO_PHY_ADDR_SHIFT) | - (devaddr << EQOS_MDIO_PHY_REG_SHIFT) | - ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | - (EQOS_MDIO_PHY_REG_WRITE) | (EQOS_MAC_GMII_BUSY)); - } else { - mac_gmiidr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); - mac_gmiidr = ((mac_gmiidr & EQOS_MAC_GMIIDR_GD_WR_MASK) | - ((phydata) & EQOS_MAC_GMIIDR_GD_MASK)); - - osi_writela(osi_core, mac_gmiidr, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); - - /* initiate the MII write operation by updating desired */ - /* phy address/id (0 - 31) */ - /* phy register offset */ - /* CSR Clock Range (20 - 35MHz) */ - /* Select write operation */ - /* set busy bit */ - mac_gmiiar = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); - mac_gmiiar = (mac_gmiiar & (EQOS_MDIO_PHY_REG_SKAP | - EQOS_MDIO_PHY_REG_C45E)); - mac_gmiiar = (mac_gmiiar | - ((phyaddr) << EQOS_MDIO_PHY_ADDR_SHIFT) | - ((phyreg) << EQOS_MDIO_PHY_REG_SHIFT) | - ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | - (EQOS_MDIO_PHY_REG_WRITE) | EQOS_MAC_GMII_BUSY); - } - - osi_writela(osi_core, mac_gmiiar, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); - /* wait for MII write operation to complete */ - return poll_for_mii_idle(osi_core); -} - -/** - * @brief eqos_read_phy_reg - Read from a PHY register through MAC over MDIO bus - * - * @note - * Algorithm: - * - Before proceeding for reading for PHY register check whether any MII - * operation going on MDIO bus by polling MAC_GMII_BUSY bit. - * - Populate required parameters like phy address, phy register etc,, - * in program it in MAC MDIO Address register. Read and GMII busy bits - * needs to be set in this operation. - * - Write into MAC MDIO address register poll for GMII busy for MDIO - * operation to complete. After this data will be available at MAC MDIO - * data register. - * - Refer to EQOS column of <> for API details. - * - Traceid:ETHERNET_NVETHERNETRM_003 - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be read from PHY. - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval data from PHY register on success - * @retval -1 on failure - */ -static nve32_t eqos_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg) -{ - nveu32_t mac_gmiiar; - nveu32_t mac_gmiidr; - nveu32_t data; - nveu32_t devaddr; - nve32_t ret = 0; - - /* Wait for any previous MII read/write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - /* poll_for_mii_idle fail */ - return ret; - } - /* C45 register access */ - if ((phyreg & OSI_MII_ADDR_C45) == OSI_MII_ADDR_C45) { - /* First write the register address */ - mac_gmiidr = (phyreg & EQOS_MDIO_DATA_REG_PHYREG_MASK) << - EQOS_MDIO_DATA_REG_PHYREG_SHIFT; - osi_writela(osi_core, mac_gmiidr, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); - - /* Extract the device address from PHY register */ - devaddr = (phyreg >> EQOS_MDIO_DATA_REG_DEV_ADDR_SHIFT) & - EQOS_MDIO_DATA_REG_DEV_ADDR_MASK; - - /* Initiate the clause 45 transaction with auto - * generation of address packet. - */ - mac_gmiiar = (EQOS_MDIO_PHY_REG_C45E | - ((phyaddr) << EQOS_MDIO_PHY_ADDR_SHIFT) | - (devaddr << EQOS_MDIO_PHY_REG_SHIFT) | - ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | - (EQOS_MDIO_PHY_REG_GOC_READ) | EQOS_MAC_GMII_BUSY); - } else { - mac_gmiiar = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); - /* initiate the MII read operation by updating desired */ - /* phy address/id (0 - 31) */ - /* phy register offset */ - /* CSR Clock Range (20 - 35MHz) */ - /* Select read operation */ - /* set busy bit */ - mac_gmiiar = (mac_gmiiar & (EQOS_MDIO_PHY_REG_SKAP | - EQOS_MDIO_PHY_REG_C45E)); - mac_gmiiar = (mac_gmiiar | - ((phyaddr) << EQOS_MDIO_PHY_ADDR_SHIFT) | - ((phyreg) << EQOS_MDIO_PHY_REG_SHIFT) | - ((osi_core->mdc_cr) << EQOS_MDIO_PHY_REG_CR_SHIF) | - (EQOS_MDIO_PHY_REG_GOC_READ) | EQOS_MAC_GMII_BUSY); - } - - osi_writela(osi_core, mac_gmiiar, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_ADDRESS); - - /* wait for MII write operation to complete */ - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - /* poll_for_mii_idle fail */ - return ret; - } - - mac_gmiidr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MDIO_DATA); - data = (mac_gmiidr & EQOS_MAC_GMIIDR_GD_MASK); - - return (nve32_t)data; -} - -/** - * @brief eqos_read_reg - Read a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval data from register on success - */ -static nveu32_t eqos_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) { - return osi_readla(osi_core, (nveu8_t *)osi_core->base + reg); -} - -/** - * @brief eqos_write_reg - Write a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t eqos_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, - const nve32_t reg) { - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + reg); - return 0; -} - -#ifdef MACSEC_SUPPORT -/** - * @brief eqos_read_macsec_reg - Read a MACSEC reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval data from register on success - */ -static nveu32_t eqos_read_macsec_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) -{ - return osi_readla(osi_core, (nveu8_t *)osi_core->macsec_base + reg); -} - -/** - * @brief eqos_write_macsec_reg - Write a MACSEC reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t eqos_write_macsec_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t reg) -{ - osi_writela(osi_core, val, (nveu8_t *)osi_core->macsec_base + reg); - return 0; -} -#endif /* MACSEC_SUPPORT */ - -#ifndef OSI_STRIPPED_LIB -/** - * @brief eqos_disable_tx_lpi - Helper function to disable Tx LPI. - * - * @note - * Algorithm: - * - Clear the bits to enable Tx LPI, Tx LPI automate, LPI Tx Timer and - * PHY Link status in the LPI control/status register - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MAC has to be out of reset, and clocks supplied. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void eqos_disable_tx_lpi( - struct osi_core_priv_data *const osi_core) -{ - void *addr = osi_core->base; - nveu32_t lpi_csr = 0; - - /* Disable LPI control bits */ - lpi_csr = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_MAC_LPI_CSR); - lpi_csr &= ~(EQOS_MAC_LPI_CSR_LPITE | EQOS_MAC_LPI_CSR_LPITXA | - EQOS_MAC_LPI_CSR_PLS | EQOS_MAC_LPI_CSR_LPIEN); - osi_writela(osi_core, lpi_csr, - (nveu8_t *)addr + EQOS_MAC_LPI_CSR); -} - -/** - * @brief Read-validate HW registers for functional safety. - * - * @note - * Algorithm: - * - Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC has to be out of reset. - * - osi_hw_core_init has to be called. Internally this would initialize - * the safety_config (see osi_core_priv_data) based on MAC version and - * which specific registers needs to be validated periodically. - * - Invoke this call if (osi_core_priv_data->safety_config != OSI_NULL) - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_validate_core_regs( - struct osi_core_priv_data *const osi_core) -{ - struct core_func_safety *config = - (struct core_func_safety *)osi_core->safety_config; - nveu32_t cur_val; - nveu32_t i; - - osi_lock_irq_enabled(&config->core_safety_lock); - for (i = EQOS_MAC_MCR_IDX; i < EQOS_MAX_CORE_SAFETY_REGS; i++) { - if (config->reg_addr[i] == OSI_NULL) { - continue; - } - cur_val = osi_readla(osi_core, - (nveu8_t *)config->reg_addr[i]); - cur_val &= config->reg_mask[i]; - - if (cur_val == config->reg_val[i]) { - continue; - } else { - /* Register content differs from what was written. - * Return error and let safety manager (NVGaurd etc.) - * take care of corrective action. - */ - osi_unlock_irq_enabled(&config->core_safety_lock); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "register mismatch\n", 0ULL); - return -1; - } - } - osi_unlock_irq_enabled(&config->core_safety_lock); - - return 0; -} - -/** - * @brief eqos_config_rx_crc_check - Configure CRC Checking for Rx Packets - * - * @note - * Algorithm: - * - When this bit is set, the MAC receiver does not check the CRC - * field in the received packets. When this bit is reset, the MAC receiver - * always checks the CRC field in the received packets. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] crc_chk: Enable or disable checking of CRC field in received pkts - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_rx_crc_check( - struct osi_core_priv_data *const osi_core, - const nveu32_t crc_chk) -{ - void *addr = osi_core->base; - nveu32_t val; - - /* return on invalid argument */ - if ((crc_chk != OSI_ENABLE) && (crc_chk != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "rx_crc: invalid input\n", 0ULL); - return -1; - } - - /* Read MAC Extension Register */ - val = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_EXTR); - - /* crc_chk: 1 is for enable and 0 is for disable */ - if (crc_chk == OSI_ENABLE) { - /* Enable Rx packets CRC check */ - val &= ~EQOS_MAC_EXTR_DCRCC; - } else if (crc_chk == OSI_DISABLE) { - /* Disable Rx packets CRC check */ - val |= EQOS_MAC_EXTR_DCRCC; - } else { - /* Nothing here */ - } - - /* Write to MAC Extension Register */ - osi_writela(osi_core, val, (nveu8_t *)addr + EQOS_MAC_EXTR); - - return 0; -} - -/** - * @brief eqos_config_tx_status - Configure MAC to forward the tx pkt status - * - * @note - * Algorithm: - * - When DTXSTS bit is reset, the Tx packet status received - * from the MAC is forwarded to the application. - * When DTXSTS bit is set, the Tx packet status received from the MAC - * are dropped in MTL. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_status: Enable or Disable the forwarding of tx pkt status - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_tx_status(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_status) -{ - void *addr = osi_core->base; - nveu32_t val; - - /* don't allow if tx_status is other than 0 or 1 */ - if ((tx_status != OSI_ENABLE) && (tx_status != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "tx_status: invalid input\n", 0ULL); - return -1; - } - - /* Read MTL Operation Mode Register */ - val = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MTL_OP_MODE); - - if (tx_status == OSI_ENABLE) { - /* When DTXSTS bit is reset, the Tx packet status received - * from the MAC are forwarded to the application. - */ - val &= ~EQOS_MTL_OP_MODE_DTXSTS; - } else if (tx_status == OSI_DISABLE) { - /* When DTXSTS bit is set, the Tx packet status received from - * the MAC are dropped in the MTL - */ - val |= EQOS_MTL_OP_MODE_DTXSTS; - } else { - /* Nothing here */ - } - - /* Write to DTXSTS bit of MTL Operation Mode Register to enable or - * disable the Tx packet status - */ - osi_writela(osi_core, val, (nveu8_t *)addr + EQOS_MTL_OP_MODE); - - return 0; -} - -/** - * @brief eqos_set_avb_algorithm - Set TxQ/TC avb config - * - * @note - * Algorithm: - * - Check if queue index is valid - * - Update operation mode of TxQ/TC - * - Set TxQ operation mode - * - Set Algo and Credit control - * - Set Send slope credit - * - Set Idle slope credit - * - Set Hi credit - * - Set low credit - * - Update register values - * - * @param[in] osi_core: OSI core priv data structure - * @param[in] avb: structure having configuration for avb algorithm - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_set_avb_algorithm( - struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *const avb) -{ - nveu32_t value; - nve32_t ret = -1; - nveu32_t qinx; - - if (avb == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", 0ULL); - return ret; - } - - /* queue index in range */ - if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", (nveul64_t)avb->qindex); - return ret; - } - - /* queue oper_mode in range check*/ - if (avb->oper_mode >= OSI_MTL_QUEUE_MODEMAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue mode\n", (nveul64_t)avb->qindex); - return ret; - } - - /* can't set AVB mode for queue 0 */ - if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "Not allowed to set AVB for Q0\n", - (nveul64_t)avb->qindex); - return ret; - } - - qinx = avb->qindex; - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); - value &= ~EQOS_MTL_TXQEN_MASK; - /* Set TxQ/TC mode as per input struct after masking 3 bit */ - value |= (avb->oper_mode << EQOS_MTL_TXQEN_MASK_SHIFT) & - EQOS_MTL_TXQEN_MASK; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx), - EQOS_MTL_CH0_TX_OP_MODE_IDX + qinx); - - /* Set Algo and Credit control */ - value = OSI_DISABLE; - if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { - value = (avb->credit_control << EQOS_MTL_TXQ_ETS_CR_CC_SHIFT) & - EQOS_MTL_TXQ_ETS_CR_CC; - } - value |= (avb->algo << EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT) & - EQOS_MTL_TXQ_ETS_CR_AVALG; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_CR(qinx)); - - if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { - /* Set Send slope credit */ - value = avb->send_slope & EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(qinx)); - - /* Set Idle slope credit*/ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); - value &= ~EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; - value |= avb->idle_slope & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; - eqos_core_safety_writel(osi_core, value, - (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx), - EQOS_MTL_TXQ0_QW_IDX + qinx); - - /* Set Hi credit */ - value = avb->hi_credit & EQOS_MTL_TXQ_ETS_HCR_HC_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); - - /* low credit is -ve number, osi_write need a nveu32_t - * take only 28:0 bits from avb->low_credit - */ - value = avb->low_credit & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); - } - - return 0; -} - -/** - * @brief eqos_get_avb_algorithm - Get TxQ/TC avb config - * - * @note - * Algorithm: - * - Check if queue index is valid - * - read operation mode of TxQ/TC - * - read TxQ operation mode - * - read Algo and Credit control - * - read Send slope credit - * - read Idle slope credit - * - read Hi credit - * - read low credit - * - updated pointer - * - * @param[in] osi_core: OSI core priv data structure - * @param[out] avb: structure pointer having configuration for avb algorithm - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_get_avb_algorithm(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb) -{ - nveu32_t value; - nve32_t ret = -1; - nveu32_t qinx = 0U; - - if (avb == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", 0ULL); - return ret; - } - - if (avb->qindex >= OSI_EQOS_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", (nveul64_t)avb->qindex); - return ret; - } - - qinx = avb->qindex; - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_CHX_TX_OP_MODE(qinx)); - - /* Get TxQ/TC mode as per input struct after masking 3:2 bit */ - value = (value & EQOS_MTL_TXQEN_MASK) >> EQOS_MTL_TXQEN_MASK_SHIFT; - avb->oper_mode = value; - - /* Get Algo and Credit control */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_CR(qinx)); - avb->credit_control = (value & EQOS_MTL_TXQ_ETS_CR_CC) >> - EQOS_MTL_TXQ_ETS_CR_CC_SHIFT; - avb->algo = (value & EQOS_MTL_TXQ_ETS_CR_AVALG) >> - EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT; - - /* Get Send slope credit */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_SSCR(qinx)); - avb->send_slope = value & EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK; - - /* Get Idle slope credit*/ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_QW(qinx)); - avb->idle_slope = value & EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK; - - /* Get Hi credit */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_HCR(qinx)); - avb->hi_credit = value & EQOS_MTL_TXQ_ETS_HCR_HC_MASK; - - /* Get Low credit for which bit 31:29 are unknown - * return 28:0 valid bits to application - */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MTL_TXQ_ETS_LCR(qinx)); - avb->low_credit = value & EQOS_MTL_TXQ_ETS_LCR_LC_MASK; - - return 0; -} - -/** - * @brief eqos_config_arp_offload - Enable/Disable ARP offload - * - * @note - * Algorithm: - * - Read the MAC configuration register - * - If ARP offload is to be enabled, program the IP address in - * ARPPA register - * - Enable/disable the ARPEN bit in MCR and write back to the MCR. - * - * @param[in] osi_core: OSI core priv data structure - * @param[in] enable: Flag variable to enable/disable ARP offload - * @param[in] ip_addr: IP address of device to be programmed in HW. - * HW will use this IP address to respond to ARP requests. - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - Valid 4 byte IP address as argument ip_addr - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_arp_offload( - struct osi_core_priv_data *const osi_core, - const nveu32_t enable, - const nveu8_t *ip_addr) -{ - void *addr = osi_core->base; - nveu32_t mac_ver = osi_core->mac_ver; - nveu32_t mac_mcr; - nveu32_t val; - - mac_mcr = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - - if (enable == OSI_ENABLE) { - val = (((nveu32_t)ip_addr[0]) << 24) | - (((nveu32_t)ip_addr[1]) << 16) | - (((nveu32_t)ip_addr[2]) << 8) | - (((nveu32_t)ip_addr[3])); - - if (mac_ver == OSI_EQOS_MAC_4_10) { - osi_writela(osi_core, val, (nveu8_t *)addr + - EQOS_4_10_MAC_ARPPA); - } else if (mac_ver == OSI_EQOS_MAC_5_00) { - osi_writela(osi_core, val, (nveu8_t *)addr + - EQOS_5_00_MAC_ARPPA); - } else { - /* Unsupported MAC ver */ - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "arp_offload: invalid HW\n", 0ULL); - return -1; - } - - mac_mcr |= EQOS_MCR_ARPEN; - } else { - mac_mcr &= ~EQOS_MCR_ARPEN; - } - - eqos_core_safety_writel(osi_core, mac_mcr, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - - return 0; -} - -/** - * @brief eqos_config_vlan_filter_reg - config vlan filter register - * - * @note - * Algorithm: - * - This sequence is used to enable/disable VLAN filtering and - * also selects VLAN filtering mode- perfect/hash - * - * @param[in] osi_core: OSI core priv data structure - * @param[in] filter_enb_dis: vlan filter enable/disable - * @param[in] perfect_hash_filtering: perfect or hash filter - * @param[in] perfect_inverse_match: normal or inverse filter - * - * @pre - * - MAC should be initialized and started. see osi_start_mac() - * - osi_core->osd should be populated. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_vlan_filtering( - struct osi_core_priv_data *const osi_core, - const nveu32_t filter_enb_dis, - const nveu32_t perfect_hash_filtering, - const nveu32_t perfect_inverse_match) -{ - nveu32_t value; - void *base = osi_core->base; - - if ((filter_enb_dis != OSI_ENABLE) && - (filter_enb_dis != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); - return -1; - } - - if ((perfect_hash_filtering != OSI_ENABLE) && - (perfect_hash_filtering != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); - return -1; - } - - if ((perfect_inverse_match != OSI_ENABLE) && - (perfect_inverse_match != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "vlan_filter: invalid input\n", 0ULL); - return -1; - } - - value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_PFR); - value &= ~(EQOS_MAC_PFR_VTFE); - value |= ((filter_enb_dis << EQOS_MAC_PFR_SHIFT) & EQOS_MAC_PFR_VTFE); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)base + EQOS_MAC_PFR, - EQOS_MAC_PFR_IDX); - - value = osi_readla(osi_core, (nveu8_t *)base + EQOS_MAC_VLAN_TR); - value &= ~(EQOS_MAC_VLAN_TR_VTIM | EQOS_MAC_VLAN_TR_VTHM); - value |= ((perfect_inverse_match << EQOS_MAC_VLAN_TR_VTIM_SHIFT) & - EQOS_MAC_VLAN_TR_VTIM); - if (perfect_hash_filtering == OSI_HASH_FILTER_MODE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "VLAN hash filter is not supported, no update of VTHM\n", - 0ULL); - } - - osi_writela(osi_core, value, (nveu8_t *)base + EQOS_MAC_VLAN_TR); - return 0; -} - -/** - * @brief eqos_configure_eee - Configure the EEE LPI mode - * - * @note - * Algorithm: - * - This routine configures EEE LPI mode in the MAC. - * - The time (in microsecond) to wait before resuming transmission after - * exiting from LPI, - * - The time (in millisecond) to wait before LPI pattern can be - * transmitted after PHY link is up) are not configurable. Default values - * are used in this routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_lpi_enabled: enable (1)/disable (0) flag for Tx lpi - * @param[in] tx_lpi_timer: Tx LPI entry timer in usec. Valid upto - * OSI_MAX_TX_LPI_TIMER in steps of 8usec. - * - * @pre - * - Required clks and resets has to be enabled. - * - MAC/PHY should be initialized - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_configure_eee(struct osi_core_priv_data *const osi_core, - const nveu32_t tx_lpi_enabled, - const nveu32_t tx_lpi_timer) -{ - nveu32_t lpi_csr = 0; - nveu32_t lpi_timer_ctrl = 0; - nveu32_t lpi_entry_timer = 0; - nveu32_t lpi_1US_tic_counter = OSI_LPI_1US_TIC_COUNTER_DEFAULT; - nveu8_t *addr = (nveu8_t *)osi_core->base; - - if (tx_lpi_enabled != OSI_DISABLE) { - /* Configure the following timers. - * 1. LPI LS timer - minimum time (in milliseconds) for - * which the link status from PHY should be up before - * the LPI pattern can be transmitted to the PHY. - * Default 1sec - * 2. LPI TW timer - minimum time (in microseconds) for - * which MAC waits after it stops transmitting LPI - * pattern before resuming normal tx. Default 21us - * 3. LPI entry timer - Time in microseconds that MAC - * will wait to enter LPI mode after all tx is complete. - * Default 1sec - */ - lpi_timer_ctrl |= ((OSI_DEFAULT_LPI_LS_TIMER & - OSI_LPI_LS_TIMER_MASK) << - OSI_LPI_LS_TIMER_SHIFT); - lpi_timer_ctrl |= (OSI_DEFAULT_LPI_TW_TIMER & - OSI_LPI_TW_TIMER_MASK); - osi_writela(osi_core, lpi_timer_ctrl, - addr + EQOS_MAC_LPI_TIMER_CTRL); - - lpi_entry_timer |= (tx_lpi_timer & - OSI_LPI_ENTRY_TIMER_MASK); - osi_writela(osi_core, lpi_entry_timer, - addr + EQOS_MAC_LPI_EN_TIMER); - /* Program the MAC_1US_Tic_Counter as per the frequency of the - * clock used for accessing the CSR slave - */ - /* fix cert error */ - if (osi_core->csr_clk_speed > 1U) { - lpi_1US_tic_counter = ((osi_core->csr_clk_speed - 1U) & - OSI_LPI_1US_TIC_COUNTER_MASK); - } - osi_writela(osi_core, lpi_1US_tic_counter, - addr + EQOS_MAC_1US_TIC_CNTR); - - /* Set LPI timer enable and LPI Tx automate, so that MAC - * can enter/exit Tx LPI on its own using timers above. - * Set LPI Enable & PHY links status (PLS) up. - */ - lpi_csr = osi_readla(osi_core, addr + EQOS_MAC_LPI_CSR); - lpi_csr |= (EQOS_MAC_LPI_CSR_LPITE | - EQOS_MAC_LPI_CSR_LPITXA | - EQOS_MAC_LPI_CSR_PLS | - EQOS_MAC_LPI_CSR_LPIEN); - osi_writela(osi_core, lpi_csr, addr + EQOS_MAC_LPI_CSR); - } else { - /* Disable LPI control bits */ - eqos_disable_tx_lpi(osi_core); - } -} - -/** - * @brief Function to store a backup of MAC register space during SOC suspend. - * - * @note - * Algorithm: - * - Read registers to be backed up as per struct core_backup and - * store the register values in memory. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on Success - */ -static inline nve32_t eqos_save_registers( - struct osi_core_priv_data *const osi_core) -{ - nveu32_t i; - struct core_backup *config = &osi_core->backup_config; - - for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - config->reg_val[i] = osi_readla(osi_core, - config->reg_addr[i]); - } - } - - return 0; -} - -/** - * @brief Function to restore the backup of MAC registers during SOC resume. - * - * @note - * Algorithm: - * - Restore the register values from the in memory backup taken using - * eqos_save_registers(). - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on Success - */ -static inline nve32_t eqos_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - nveu32_t i; - struct core_backup *config = &osi_core->backup_config; - - for (i = 0; i < EQOS_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - osi_writela(osi_core, config->reg_val[i], - config->reg_addr[i]); - } - } - - return 0; -} - -/** - * @brief eqos_set_mdc_clk_rate - Derive MDC clock based on provided AXI_CBB clk - * - * @note - * Algorithm: - * - MDC clock rate will be populated OSI core private data structure - * based on AXI_CBB clock rate. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] csr_clk_rate: CSR (AXI CBB) clock rate. - * - * @pre OSD layer needs get the AXI CBB clock rate with OSD clock API - * (ex - clk_get_rate()) - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_set_mdc_clk_rate(struct osi_core_priv_data *const osi_core, - const nveu64_t csr_clk_rate) -{ - nveu64_t csr_clk_speed = csr_clk_rate / 1000000UL; - - /* store csr clock speed used in programming - * LPI 1us tick timer register - */ - if (csr_clk_speed <= UINT_MAX) { - osi_core->csr_clk_speed = (nveu32_t)csr_clk_speed; - } - if (csr_clk_speed > 500UL) { - osi_core->mdc_cr = EQOS_CSR_500_800M; - } else if (csr_clk_speed > 300UL) { - osi_core->mdc_cr = EQOS_CSR_300_500M; - } else if (csr_clk_speed > 250UL) { - osi_core->mdc_cr = EQOS_CSR_250_300M; - } else if (csr_clk_speed > 150UL) { - osi_core->mdc_cr = EQOS_CSR_150_250M; - } else if (csr_clk_speed > 100UL) { - osi_core->mdc_cr = EQOS_CSR_100_150M; - } else if (csr_clk_speed > 60UL) { - osi_core->mdc_cr = EQOS_CSR_60_100M; - } else if (csr_clk_speed > 35UL) { - osi_core->mdc_cr = EQOS_CSR_35_60M; - } else { - /* for CSR < 35mhz */ - osi_core->mdc_cr = EQOS_CSR_20_35M; - } -} - -/** - * @brief eqos_config_mac_loopback - Configure MAC to support loopback - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lb_mode: Enable or Disable MAC loopback mode - * - * @pre MAC should be initialized and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_config_mac_loopback( - struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode) -{ - nveu32_t clk_ctrl_val; - nveu32_t mcr_val; - void *addr = osi_core->base; - - /* Read MAC Configuration Register */ - mcr_val = osi_readla(osi_core, (nveu8_t *)addr + EQOS_MAC_MCR); - - /* Read EQOS wrapper clock control 0 register */ - clk_ctrl_val = osi_readla(osi_core, - (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); - - if (lb_mode == OSI_ENABLE) { - /* Enable Loopback Mode */ - mcr_val |= EQOS_MAC_ENABLE_LM; - /* Enable RX_CLK_SEL so that TX Clock is fed to RX domain */ - clk_ctrl_val |= EQOS_RX_CLK_SEL; - } else if (lb_mode == OSI_DISABLE){ - /* Disable Loopback Mode */ - mcr_val &= ~EQOS_MAC_ENABLE_LM; - /* Disable RX_CLK_SEL so that TX Clock is fed to RX domain */ - clk_ctrl_val &= ~EQOS_RX_CLK_SEL; - } else { - /* Nothing here */ - } - - /* Write to EQOS wrapper clock control 0 register */ - osi_writela(osi_core, clk_ctrl_val, - (nveu8_t *)addr + EQOS_CLOCK_CTRL_0); - - /* Write to MAC Configuration Register */ - eqos_core_safety_writel(osi_core, mcr_val, - (nveu8_t *)addr + EQOS_MAC_MCR, - EQOS_MAC_MCR_IDX); - - return 0; -} -#endif /* !OSI_STRIPPED_LIB */ - -static nve32_t eqos_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat) -{ - nveu32_t mac_hfr0 = 0; - nveu32_t mac_hfr1 = 0; - nveu32_t mac_hfr2 = 0; - nveu32_t mac_hfr3 = 0; - - mac_hfr0 = eqos_read_reg(osi_core, EQOS_MAC_HFR0); - mac_hfr1 = eqos_read_reg(osi_core, EQOS_MAC_HFR1); - mac_hfr2 = eqos_read_reg(osi_core, EQOS_MAC_HFR2); - mac_hfr3 = eqos_read_reg(osi_core, EQOS_MAC_HFR3); - - hw_feat->mii_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_MIISEL_SHIFT) & - EQOS_MAC_HFR0_MIISEL_MASK); - hw_feat->gmii_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_GMIISEL_SHIFT) & - EQOS_MAC_HFR0_GMIISEL_MASK); - hw_feat->hd_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_HDSEL_SHIFT) & - EQOS_MAC_HFR0_HDSEL_MASK); - hw_feat->pcs_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_PCSSEL_SHIFT) & - EQOS_MAC_HFR0_PCSSEL_MASK); - hw_feat->vlan_hash_en = ((mac_hfr0 >> EQOS_MAC_HFR0_VLHASH_SHIFT) & - EQOS_MAC_HFR0_VLHASH_MASK); - hw_feat->sma_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_SMASEL_SHIFT) & - EQOS_MAC_HFR0_SMASEL_MASK); - hw_feat->rwk_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_RWKSEL_SHIFT) & - EQOS_MAC_HFR0_RWKSEL_MASK); - hw_feat->mgk_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_MGKSEL_SHIFT) & - EQOS_MAC_HFR0_MGKSEL_MASK); - hw_feat->mmc_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_MMCSEL_SHIFT) & - EQOS_MAC_HFR0_MMCSEL_MASK); - hw_feat->arp_offld_en = ((mac_hfr0 >> EQOS_MAC_HFR0_ARPOFFLDEN_SHIFT) & - EQOS_MAC_HFR0_ARPOFFLDEN_MASK); - hw_feat->ts_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_TSSSEL_SHIFT) & - EQOS_MAC_HFR0_TSSSEL_MASK); - hw_feat->eee_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_EEESEL_SHIFT) & - EQOS_MAC_HFR0_EEESEL_MASK); - hw_feat->tx_coe_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_TXCOESEL_SHIFT) & - EQOS_MAC_HFR0_TXCOESEL_MASK); - hw_feat->rx_coe_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_RXCOE_SHIFT) & - EQOS_MAC_HFR0_RXCOE_MASK); - hw_feat->mac_addr_sel = - ((mac_hfr0 >> EQOS_MAC_HFR0_ADDMACADRSEL_SHIFT) & - EQOS_MAC_HFR0_ADDMACADRSEL_MASK); - hw_feat->mac_addr32_sel = - ((mac_hfr0 >> EQOS_MAC_HFR0_MACADR32SEL_SHIFT) & - EQOS_MAC_HFR0_MACADR32SEL_MASK); - hw_feat->mac_addr64_sel = - ((mac_hfr0 >> EQOS_MAC_HFR0_MACADR64SEL_SHIFT) & - EQOS_MAC_HFR0_MACADR64SEL_MASK); - hw_feat->tsstssel = ((mac_hfr0 >> EQOS_MAC_HFR0_TSINTSEL_SHIFT) & - EQOS_MAC_HFR0_TSINTSEL_MASK); - hw_feat->sa_vlan_ins = ((mac_hfr0 >> EQOS_MAC_HFR0_SAVLANINS_SHIFT) & - EQOS_MAC_HFR0_SAVLANINS_MASK); - hw_feat->act_phy_sel = ((mac_hfr0 >> EQOS_MAC_HFR0_ACTPHYSEL_SHIFT) & - EQOS_MAC_HFR0_ACTPHYSEL_MASK); - hw_feat->rx_fifo_size = ((mac_hfr1 >> EQOS_MAC_HFR1_RXFIFOSIZE_SHIFT) & - EQOS_MAC_HFR1_RXFIFOSIZE_MASK); - hw_feat->tx_fifo_size = ((mac_hfr1 >> EQOS_MAC_HFR1_TXFIFOSIZE_SHIFT) & - EQOS_MAC_HFR1_TXFIFOSIZE_MASK); - hw_feat->ost_en = ((mac_hfr1 >> EQOS_MAC_HFR1_OSTEN_SHIFT) & - EQOS_MAC_HFR1_OSTEN_MASK); - hw_feat->pto_en = ((mac_hfr1 >> EQOS_MAC_HFR1_PTOEN_SHIFT) & - EQOS_MAC_HFR1_PTOEN_MASK); - hw_feat->adv_ts_hword = ((mac_hfr1 >> EQOS_MAC_HFR1_ADVTHWORD_SHIFT) & - EQOS_MAC_HFR1_ADVTHWORD_MASK); - hw_feat->addr_64 = ((mac_hfr1 >> EQOS_MAC_HFR1_ADDR64_SHIFT) & - EQOS_MAC_HFR1_ADDR64_MASK); - hw_feat->dcb_en = ((mac_hfr1 >> EQOS_MAC_HFR1_DCBEN_SHIFT) & - EQOS_MAC_HFR1_DCBEN_MASK); - hw_feat->sph_en = ((mac_hfr1 >> EQOS_MAC_HFR1_SPHEN_SHIFT) & - EQOS_MAC_HFR1_SPHEN_MASK); - hw_feat->tso_en = ((mac_hfr1 >> EQOS_MAC_HFR1_TSOEN_SHIFT) & - EQOS_MAC_HFR1_TSOEN_MASK); - hw_feat->dma_debug_gen = - ((mac_hfr1 >> EQOS_MAC_HFR1_DMADEBUGEN_SHIFT) & - EQOS_MAC_HFR1_DMADEBUGEN_MASK); - hw_feat->av_sel = ((mac_hfr1 >> EQOS_MAC_HFR1_AVSEL_SHIFT) & - EQOS_MAC_HFR1_AVSEL_MASK); - hw_feat->rav_sel = ((mac_hfr1 >> EQOS_MAC_HFR1_RAVSEL_SHIFT) & - EQOS_MAC_HFR1_RAVSEL_MASK); - hw_feat->ost_over_udp = ((mac_hfr1 >> EQOS_MAC_HFR1_POUOST_SHIFT) & - EQOS_MAC_HFR1_POUOST_MASK); - hw_feat->hash_tbl_sz = ((mac_hfr1 >> EQOS_MAC_HFR1_HASHTBLSZ_SHIFT) & - EQOS_MAC_HFR1_HASHTBLSZ_MASK); - hw_feat->l3l4_filter_num = - ((mac_hfr1 >> EQOS_MAC_HFR1_L3L4FILTERNUM_SHIFT) & - EQOS_MAC_HFR1_L3L4FILTERNUM_MASK); - hw_feat->rx_q_cnt = ((mac_hfr2 >> EQOS_MAC_HFR2_RXQCNT_SHIFT) & - EQOS_MAC_HFR2_RXQCNT_MASK); - hw_feat->tx_q_cnt = ((mac_hfr2 >> EQOS_MAC_HFR2_TXQCNT_SHIFT) & - EQOS_MAC_HFR2_TXQCNT_MASK); - hw_feat->rx_ch_cnt = ((mac_hfr2 >> EQOS_MAC_HFR2_RXCHCNT_SHIFT) & - EQOS_MAC_HFR2_RXCHCNT_MASK); - hw_feat->tx_ch_cnt = ((mac_hfr2 >> EQOS_MAC_HFR2_TXCHCNT_SHIFT) & - EQOS_MAC_HFR2_TXCHCNT_MASK); - hw_feat->pps_out_num = ((mac_hfr2 >> EQOS_MAC_HFR2_PPSOUTNUM_SHIFT) & - EQOS_MAC_HFR2_PPSOUTNUM_MASK); - hw_feat->aux_snap_num = ((mac_hfr2 >> EQOS_MAC_HFR2_AUXSNAPNUM_SHIFT) & - EQOS_MAC_HFR2_AUXSNAPNUM_MASK); - hw_feat->num_vlan_filters = ((mac_hfr3 >> EQOS_MAC_HFR3_NRVF_SHIFT) & - EQOS_MAC_HFR3_NRVF_MASK); - hw_feat->cbti_sel = ((mac_hfr3 >> EQOS_MAC_HFR3_CBTISEL_SHIFT) & - EQOS_MAC_HFR3_CBTISEL_MASK); - hw_feat->double_vlan_en = ((mac_hfr3 >> EQOS_MAC_HFR3_DVLAN_SHIFT) & - EQOS_MAC_HFR3_DVLAN_MASK); - /* TODO: packet duplication feature */ - hw_feat->frp_sel = ((mac_hfr3 >> EQOS_MAC_HFR3_FRPSEL_SHIFT) & - EQOS_MAC_HFR3_FRPSEL_MASK); - hw_feat->max_frp_bytes = ((mac_hfr3 >> EQOS_MAC_HFR3_FRPPB_SHIFT) & - EQOS_MAC_HFR3_FRPPB_MASK); - hw_feat->max_frp_entries = ((mac_hfr3 >> EQOS_MAC_HFR3_FRPES_SHIFT) & - EQOS_MAC_HFR3_FRPES_MASK); - hw_feat->est_sel = ((mac_hfr3 >> EQOS_MAC_HFR3_ESTSEL_SHIFT) & - EQOS_MAC_HFR3_ESTSEL_MASK); - hw_feat->gcl_depth = ((mac_hfr3 >> EQOS_MAC_HFR3_GCLDEP_SHIFT) & - EQOS_MAC_HFR3_GCLDEP_MASK); - hw_feat->gcl_width = ((mac_hfr3 >> EQOS_MAC_HFR3_GCLWID_SHIFT) & - EQOS_MAC_HFR3_GCLWID_MASK); - hw_feat->fpe_sel = ((mac_hfr3 >> EQOS_MAC_HFR3_FPESEL_SHIFT) & - EQOS_MAC_HFR3_FPESEL_MASK); - hw_feat->tbs_sel = ((mac_hfr3 >> EQOS_MAC_HFR3_TBSSEL_SHIFT) & - EQOS_MAC_HFR3_TBSSEL_MASK); - hw_feat->auto_safety_pkg = ((mac_hfr3 >> EQOS_MAC_HFR3_ASP_SHIFT) & - EQOS_MAC_HFR3_ASP_MASK); - return 0; -} - -#ifdef UPDATED_PAD_CAL -/** - * @brief eqos_padctl_rx_pins Enable/Disable RGMII Rx pins - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] enable: Enable/Disable EQOS RGMII padctrl Rx pins - * - * @pre - * - MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int eqos_padctl_rx_pins(struct osi_core_priv_data *const osi_core, - unsigned int enable) -{ - nveu32_t value; - void *pad_addr = osi_core->padctrl.padctrl_base; - - if (pad_addr == OSI_NULL) { - return -1; - } - if (enable == OSI_ENABLE) { - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rx_ctl); - value |= EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rx_ctl); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd0); - value |= EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd0); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd1); - value |= EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd1); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd2); - value |= EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd2); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd3); - value |= EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd3); - } else { - value = osi_readla(osi_core, (unsigned char *)pad_addr + - osi_core->padctrl.offset_rx_ctl); - value &= ~EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rx_ctl); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd0); - value &= ~EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd0); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd1); - value &= ~EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd1); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd2); - value &= ~EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd2); - value = osi_readla(osi_core, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd3); - value &= ~EQOS_PADCTL_EQOS_E_INPUT; - osi_writela(osi_core, value, (nveu8_t *)pad_addr + - osi_core->padctrl.offset_rd3); - } - return 0; -} - -/** - * @brief poll_for_mac_tx_rx_idle - check mac tx/rx idle or not - * - * Algorithm: Check MAC tx/rx engines are idle. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @pre - * - MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int poll_for_mac_tx_rx_idle(struct osi_core_priv_data *osi_core) -{ - nveu32_t retry = 0; - nveu32_t mac_debug; - - while (retry < OSI_TXRX_IDLE_RETRY) { - mac_debug = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_DEBUG); - if (((mac_debug & EQOS_MAC_DEBUG_RPESTS) != - EQOS_MAC_DEBUG_RPESTS) && - ((mac_debug & EQOS_MAC_DEBUG_TPESTS) != - EQOS_MAC_DEBUG_TPESTS)) { - break; - } - /* wait */ - osi_core->osd_ops.udelay(OSI_DELAY_COUNT); - retry++; - } - if (retry >= OSI_TXRX_IDLE_RETRY) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, "RGMII idle timed out\n", - mac_debug); - return -1; - } - - return 0; -} - -/** - * @brief eqos_pre_pad_calibrate - pre PAD calibration - * - * Algorithm: - * - Disable interrupt RGSMIIIE bit in MAC_Interrupt_Enable register - * - Stop MAC - * - Check MDIO interface idle and ensure no read/write to MDIO interface - * - Wait for MII idle (Ensure MAC_Debug register value is 0) - * - Disable RGMII Rx traffic by disabling padctl pins - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - * @retval 0 on success - * @retval negative value on failure. - */ - -static int eqos_pre_pad_calibrate(struct osi_core_priv_data *const osi_core) -{ - nve32_t ret = 0; - nveu32_t value; - - /* Disable MAC RGSMIIIE - RGMII/SMII interrupts */ - /* Read MAC IMR Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + EQOS_MAC_IMR); - value &= ~(EQOS_IMR_RGSMIIIE); - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - eqos_stop_mac(osi_core); - ret = poll_for_mii_idle(osi_core); - if (ret < 0) { - goto error; - } - - ret = poll_for_mac_tx_rx_idle(osi_core); - if (ret < 0) { - goto error; - } - - if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, - OSI_DISABLE); - } else { - ret = eqos_padctl_rx_pins(osi_core, OSI_DISABLE); - } - if (ret < 0) { - goto error; - } - - return ret; -error: - /* roll back on fail */ - eqos_start_mac(osi_core); - if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - (void)osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, - OSI_ENABLE); - } else { - (void)eqos_padctl_rx_pins(osi_core, OSI_ENABLE); - } - - /* Enable MAC RGSMIIIE - RGMII/SMII interrupts */ - /* Read MAC IMR Register */ - value = osi_readl((unsigned char *)osi_core->base + EQOS_MAC_IMR); - value |= EQOS_IMR_RGSMIIIE; - eqos_core_safety_writel(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - - return ret; -} - -/** - * @brief eqos_post_pad_calibrate - post PAD calibration - * - * Algorithm: - * - Enable RGMII Rx traffic by enabling padctl pins - * - Read MAC_PHY_Control_Status register to clear any pending - * interrupts due to enable rx pad pins - * - start MAC - * - Enable interrupt RGSMIIIE bit in MAC_Interrupt_Enable register - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC should out of reset and clocks enabled. - * - * @retval 0 on success - * @retval negative value on failure. - */ -static nve32_t eqos_post_pad_calibrate( - struct osi_core_priv_data *const osi_core) -{ - nve32_t ret = 0; - nveu32_t mac_imr = 0; - nveu32_t mac_pcs = 0; - nveu32_t mac_isr = 0; - - if (osi_core->osd_ops.padctrl_mii_rx_pins != OSI_NULL) { - ret = osi_core->osd_ops.padctrl_mii_rx_pins(osi_core->osd, - OSI_ENABLE); - } else { - ret = eqos_padctl_rx_pins(osi_core, OSI_ENABLE); - } - /* handle only those MAC interrupts which are enabled */ - mac_imr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR); - mac_isr = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_ISR); - /* RGMII/SMII interrupt disabled in eqos_pre_pad_calibrate */ - if ((mac_isr & EQOS_MAC_ISR_RGSMIIS) == EQOS_MAC_ISR_RGSMIIS && - (mac_imr & EQOS_MAC_ISR_RGSMIIS) == OSI_DISABLE) { - /* clear RGSMIIIE pending interrupt status due to pad enable */ - mac_pcs = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_PCS); - if (mac_pcs) { - /* do nothing */ - } - } - eqos_start_mac(osi_core); - /* Enable MAC RGSMIIIE - RGMII/SMII interrupts */ - mac_imr |= EQOS_IMR_RGSMIIIE; - eqos_core_safety_writel(osi_core, mac_imr, (nveu8_t *)osi_core->base + - EQOS_MAC_IMR, EQOS_MAC_IMR_IDX); - return ret; -} -#endif /* UPDATED_PAD_CAL */ - -/** - * @brief eqos_config_rss - Configure RSS - * - * Algorithm: Programes RSS hash table or RSS hash key. - * - * @param[in] osi_core: OSI core private data. - * - * @retval -1 Always - */ -static nve32_t eqos_config_rss(struct osi_core_priv_data *const osi_core) -{ - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "RSS not supported by EQOS\n", 0ULL); - - return -1; -} - -#ifdef MACSEC_SUPPORT -/** - * @brief eqos_config_for_macsec - Configure MAC according to macsec IAS - * - * @note - * Algorithm: - * - Stop MAC Tx - * - Update MAC IPG value to accommodate macsec 32 byte SECTAG. - * - Start MAC Tx - * - Update MTL_EST value as MACSEC is enabled/disabled - * - * @param[in] osi_core: OSI core private data. - * @param[in] enable: enable/disable macsec ipg value in mac - * - * @pre - * 1) MAC has to be out of reset. - * 2) Shall not use this ipg value in half duplex mode - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_config_for_macsec(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value = 0U, temp = 0U; - - if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Failed to config EQOS per MACSEC\n", 0ULL); - return; - } - if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { - /* stop MAC Tx */ - eqos_config_mac_tx(osi_core, OSI_DISABLE); - if (enable == OSI_ENABLE) { - /* Configure IPG {EIPG,IPG} value according to macsec IAS in - * MAC_Configuration and MAC_Extended_Configuration - * IPG (12 B[default] + 32 B[sectag]) = 352 bits - */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MCR); - temp = EQOS_MCR_IPG; - temp = temp << EQOS_MCR_IPG_SHIFT; - value |= temp & EQOS_MCR_IPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_MCR); - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - value |= EQOS_MAC_EXTR_EIPGEN; - temp = EQOS_MAC_EXTR_EIPG; - temp = temp << EQOS_MAC_EXTR_EIPG_SHIFT; - value |= temp & EQOS_MAC_EXTR_EIPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - } else { - /* reset to default IPG 12B */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_MCR); - value &= ~EQOS_MCR_IPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_MCR); - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - value &= ~EQOS_MAC_EXTR_EIPGEN; - value &= ~EQOS_MAC_EXTR_EIPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - EQOS_MAC_EXTR); - } - /* start MAC Tx */ - eqos_config_mac_tx(osi_core, OSI_ENABLE); - } - - if (osi_core->hw_feature != OSI_NULL) { - /* Updated MTL_EST depending on MACSEC enable/disable */ - if (osi_core->hw_feature->est_sel == OSI_ENABLE) { - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - value &= ~EQOS_MTL_EST_CONTROL_CTOV; - if (enable == OSI_ENABLE) { - temp = EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND; - temp = temp << EQOS_MTL_EST_CONTROL_CTOV_SHIFT; - value |= temp & EQOS_MTL_EST_CONTROL_CTOV; - } else { - temp = EQOS_MTL_EST_CTOV_RECOMMEND; - temp = temp << EQOS_MTL_EST_CONTROL_CTOV_SHIFT; - value |= temp & EQOS_MTL_EST_CONTROL_CTOV; - } - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + - EQOS_MTL_EST_CONTROL); - } - } else { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, "Error: osi_core->hw_feature is NULL\n", - 0ULL); - } -} - -#endif /* MACSEC_SUPPORT */ - -/** - * @brief eqos_get_core_safety_config - EQOS MAC safety configuration - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void *eqos_get_core_safety_config(void) -{ - return &eqos_core_safety_config; -} - -void eqos_init_core_ops(struct core_ops *ops) -{ - ops->poll_for_swr = eqos_poll_for_swr; - ops->core_init = eqos_core_init; - ops->core_deinit = eqos_core_deinit; - ops->start_mac = eqos_start_mac; - ops->stop_mac = eqos_stop_mac; - ops->handle_common_intr = eqos_handle_common_intr; - ops->set_mode = eqos_set_mode; - ops->set_speed = eqos_set_speed; - ops->pad_calibrate = eqos_pad_calibrate; - ops->config_fw_err_pkts = eqos_config_fw_err_pkts; - ops->config_rxcsum_offload = eqos_config_rxcsum_offload; - ops->config_mac_pkt_filter_reg = eqos_config_mac_pkt_filter_reg; - ops->update_mac_addr_low_high_reg = eqos_update_mac_addr_low_high_reg; - ops->config_l3_l4_filter_enable = eqos_config_l3_l4_filter_enable; - ops->config_l3_filters = eqos_config_l3_filters; - ops->update_ip4_addr = eqos_update_ip4_addr; - ops->update_ip6_addr = eqos_update_ip6_addr; - ops->config_l4_filters = eqos_config_l4_filters; - ops->update_l4_port_no = eqos_update_l4_port_no; - ops->set_systime_to_mac = eqos_set_systime_to_mac; - ops->config_addend = eqos_config_addend; - ops->adjust_mactime = eqos_adjust_mactime; - ops->config_tscr = eqos_config_tscr; - ops->config_ssir = eqos_config_ssir; - ops->read_mmc = eqos_read_mmc; - ops->write_phy_reg = eqos_write_phy_reg; - ops->read_phy_reg = eqos_read_phy_reg; - ops->read_reg = eqos_read_reg; - ops->write_reg = eqos_write_reg; -#ifdef MACSEC_SUPPORT - ops->read_macsec_reg = eqos_read_macsec_reg; - ops->write_macsec_reg = eqos_write_macsec_reg; -#endif /* MACSEC_SUPPORT */ - ops->get_hw_features = eqos_get_hw_features; -#ifndef OSI_STRIPPED_LIB - ops->config_tx_status = eqos_config_tx_status; - ops->config_rx_crc_check = eqos_config_rx_crc_check; - ops->config_flow_control = eqos_config_flow_control; - ops->config_arp_offload = eqos_config_arp_offload; - ops->config_ptp_offload = eqos_config_ptp_offload; - ops->validate_regs = eqos_validate_core_regs; - ops->flush_mtl_tx_queue = eqos_flush_mtl_tx_queue; - ops->set_avb_algorithm = eqos_set_avb_algorithm; - ops->get_avb_algorithm = eqos_get_avb_algorithm; - ops->config_vlan_filtering = eqos_config_vlan_filtering; - ops->reset_mmc = eqos_reset_mmc; - ops->configure_eee = eqos_configure_eee; - ops->save_registers = eqos_save_registers; - ops->restore_registers = eqos_restore_registers; - ops->set_mdc_clk_rate = eqos_set_mdc_clk_rate; - ops->config_mac_loopback = eqos_config_mac_loopback; -#endif /* !OSI_STRIPPED_LIB */ - ops->hw_config_est = eqos_hw_config_est; - ops->hw_config_fpe = eqos_hw_config_fpe; - ops->config_ptp_rxq = eqos_config_ptp_rxq; - ops->config_frp = eqos_config_frp; - ops->update_frp_entry = eqos_update_frp_entry; - ops->update_frp_nve = eqos_update_frp_nve; - ops->config_rss = eqos_config_rss; -#ifdef MACSEC_SUPPORT - ops->macsec_config_mac = eqos_config_for_macsec; -#endif /* MACSEC_SUPPORT */ - ops->ptp_tsc_capture = eqos_ptp_tsc_capture; -#ifdef HSI_SUPPORT - ops->core_hsi_configure = eqos_hsi_configure; -#endif -} diff --git a/osi/core/eqos_core.h b/osi/core/eqos_core.h deleted file mode 100644 index c3b503a..0000000 --- a/osi/core/eqos_core.h +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 INCLUDED_EQOS_CORE_H -#define INCLUDED_EQOS_CORE_H - -#ifndef OSI_STRIPPED_LIB -/** - * @addtogroup EQOS-MDC MDC Clock Selection defines - * - * @brief MDC Clock defines - * @{ - */ -#define EQOS_CSR_60_100M 0x0 /* MDC = clk_csr/42 */ -#define EQOS_CSR_100_150M 0x1 /* MDC = clk_csr/62 */ -#define EQOS_CSR_20_35M 0x2 /* MDC = clk_csr/16 */ -#define EQOS_CSR_35_60M 0x3 /* MDC = clk_csr/26 */ -#define EQOS_CSR_150_250M 0x4 /* MDC = clk_csr/102 */ -#define EQOS_CSR_250_300M 0x5 /* MDC = clk_csr/124 */ -#define EQOS_CSR_300_500M 0x6 /* MDC = clk_csr/204 */ -#define EQOS_CSR_500_800M 0x7 /* MDC = clk_csr/324 */ -/** @} */ -#endif /* !OSI_STRIPPED_LIB */ -/** - * @addtogroup EQOS-SIZE SIZE calculation helper Macros - * - * @brief SIZE calculation defines - * @{ - */ -#define FIFO_SIZE_B(x) (x) -#define FIFO_SIZE_KB(x) ((x) * 1024U) -/** @} */ - -/** - * @addtogroup EQOS-QUEUE QUEUE fifo size programmable values - * - * @brief Queue FIFO size programmable values - * @{ - */ -#define EQOS_256 0x00U -#define EQOS_512 0x01U -#define EQOS_1K 0x03U -#define EQOS_2K 0x07U -#define EQOS_4K 0x0FU -#define EQOS_8K 0x1FU -#define EQOS_9K 0x23U -#define EQOS_16K 0x3FU -#define EQOS_32K 0x7FU -#define EQOS_36K 0x8FU -/** @} */ - -/** - * @addtogroup EQOS-HW Hardware Register offsets - * - * @brief EQOS HW register offsets - * @{ - */ -#define EQOS_MAC_MCR 0x0000 -#define EQOS_MAC_EXTR 0x0004 -#define EQOS_MAC_PFR 0x0008 -#define EQOS_MAC_WATCH 0x000C -#define EQOS_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#define EQOS_MAC_VLAN_TAG 0x0050 -#define EQOS_MAC_VLANTIR 0x0060 -#define EQOS_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) -#define EQOS_MAC_RX_FLW_CTRL 0x0090 -#define EQOS_MAC_RQC0R 0x00A0 -#define EQOS_MAC_RQC1R 0x00A4 -#define EQOS_MAC_RQC2R 0x00A8 -#define EQOS_MAC_ISR 0x00B0 -#define EQOS_MAC_IMR 0x00B4 -#define EQOS_MAC_PMTCSR 0x00C0 -#define EQOS_MAC_LPI_CSR 0x00D0 -#define EQOS_MAC_LPI_TIMER_CTRL 0x00D4 -#define EQOS_MAC_LPI_EN_TIMER 0x00D8 -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAC_1US_TIC_CNTR 0x00DC -#endif /* !OSI_STRIPPED_LIB */ -#define EQOS_MAC_ANS 0x00E4 -#define EQOS_MAC_PCS 0x00F8 -#define EQOS_MAC_DEBUG 0x0114 -#define EQOS_MAC_MDIO_ADDRESS 0x0200 -#define EQOS_MAC_MDIO_DATA 0x0204 -#define EQOS_5_00_MAC_ARPPA 0x0210 -#define EQOS_MAC_CSR_SW_CTL 0x0230 -#define EQOS_MAC_FPE_CTS 0x0234 -#define EQOS_MAC_MA0HR 0x0300 -#define EQOS_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) -#define EQOS_MAC_MA0LR 0x0304 -#define EQOS_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) -#define EQOS_MMC_CNTRL 0x0700 -#define EQOS_MMC_TX_INTR_MASK 0x0710 -#define EQOS_MMC_RX_INTR_MASK 0x070C -#define EQOS_MMC_IPC_RX_INTR_MASK 0x0800 -#define EQOS_MAC_L3L4_CTR(x) ((0x0030U * (x)) + 0x0900U) -#define EQOS_MAC_L4_ADR(x) ((0x0030U * (x)) + 0x0904U) -#define EQOS_MAC_L3_AD0R(x) ((0x0030U * (x)) + 0x0910U) -#define EQOS_MAC_L3_AD1R(x) ((0x0030U * (x)) + 0x0914U) -#define EQOS_MAC_L3_AD2R(x) ((0x0030U * (x)) + 0x0918U) -#define EQOS_MAC_L3_AD3R(x) ((0x0030U * (x)) + 0x091CU) -#define EQOS_4_10_MAC_ARPPA 0x0AE0 -#define EQOS_MAC_TCR 0x0B00 -#define EQOS_MAC_SSIR 0x0B04 -#define EQOS_MAC_STSR 0x0B08 -#define EQOS_MAC_STNSR 0x0B0C -#define EQOS_MAC_STSUR 0x0B10 -#define EQOS_MAC_STNSUR 0x0B14 -#define EQOS_MAC_TAR 0x0B18 -#define EQOS_MAC_PTO_CR 0x0BC0 -#define EQOS_MAC_PIDR0 0x0BC4 -#define EQOS_MAC_PIDR1 0x0BC8 -#define EQOS_MAC_PIDR2 0x0BCC -#define EQOS_MAC_PPS_CTL 0x0B70 -#define EQOS_DMA_BMR 0x1000 -#define EQOS_DMA_SBUS 0x1004 -#define EQOS_DMA_ISR 0x1008 -/** @} */ - -/** - * @addtogroup EQOS-MTL MTL HW Register offsets - * - * @brief EQOS MTL HW Register offsets - * @{ - */ -#define EQOS_MTL_OP_MODE 0x0C00 -#define EQOS_MTL_INTR_STATUS 0x0C20 -#define EQOS_MTL_RXQ_DMA_MAP0 0x0C30 -#define EQOS_MTL_RXQ_DMA_MAP1 0x0C34 -#define EQOS_MTL_EST_CONTROL 0x0C50 -#define EQOS_MTL_EST_OVERHEAD 0x0C54 -#define EQOS_MTL_EST_STATUS 0x0C58 -#define EQOS_MTL_EST_SCH_ERR 0x0C60 -#define EQOS_MTL_EST_FRMS_ERR 0x0C64 -#define EQOS_MTL_EST_FRMC_ERR 0x0C68 -#define EQOS_MTL_EST_ITRE 0x0C70 -#define EQOS_MTL_EST_GCL_CONTROL 0x0C80 -#define EQOS_MTL_EST_DATA 0x0C84 -#define EQOS_MTL_FPE_CTS 0x0C90 -#define EQOS_MTL_FPE_ADV 0x0C94 -#define EQOS_MTL_RXP_CS 0x0CA0 -#define EQOS_MTL_RXP_INTR_CS 0x0CA4 -#define EQOS_MTL_RXP_DROP_CNT 0x0CA8 -#define EQOS_MTL_RXP_ERROR_CNT 0x0CAC -#define EQOS_MTL_RXP_IND_CS 0x0CB0 -#define EQOS_MTL_RXP_IND_DATA 0x0CB4 -#define EQOS_MTL_CHX_TX_OP_MODE(x) ((0x0040U * (x)) + 0x0D00U) -#define EQOS_MTL_TXQ_DEBUG(x) ((0x0040U * (x)) + 0x0D08U) -#define EQOS_MTL_TXQ_ETS_CR(x) ((0x0040U * (x)) + 0x0D10U) -#define EQOS_MTL_TXQ_QW(x) ((0x0040U * (x)) + 0x0D18U) -#define EQOS_MTL_TXQ_ETS_SSCR(x) ((0x0040U * (x)) + 0x0D1CU) -#define EQOS_MTL_TXQ_ETS_HCR(x) ((0x0040U * (x)) + 0x0D20U) -#define EQOS_MTL_TXQ_ETS_LCR(x) ((0x0040U * (x)) + 0x0D24U) -#define EQOS_MTL_CHX_RX_OP_MODE(x) ((0x0040U * (x)) + 0x0D30U) -#define EQOS_MTL_RXQ_DEBUG(x) ((0x0040U * (x)) + 0x0D38U) -/** @} */ - -/** - * @addtogroup EQOS-Wrapper EQOS Wrapper HW Register offsets - * - * @brief EQOS Wrapper register offsets - * @{ - */ -#define EQOS_CLOCK_CTRL_0 0x8000U -#define EQOS_APB_ERR_STATUS 0x8214U -#define EQOS_AXI_ASID_CTRL 0x8400U -#define EQOS_AXI_ASID1_CTRL 0x8404U -#define EQOS_PAD_CRTL 0x8800U -#define EQOS_PAD_AUTO_CAL_CFG 0x8804U -#define EQOS_PAD_AUTO_CAL_STAT 0x880CU -#define EQOS_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) -#define VIRTUAL_APB_ERR_CTRL 0x8300 -#define EQOS_WRAP_COMMON_INTR_ENABLE 0x8704 -#define EQOS_REGISTER_PARITY_ERR OSI_BIT(5) -#define EQOS_CORE_CORRECTABLE_ERR OSI_BIT(4) -#define EQOS_CORE_UNCORRECTABLE_ERR OSI_BIT(3) -#define EQOS_MAC_SBD_INTR OSI_BIT(2) -#define EQOS_WRAP_COMMON_INTR_STATUS 0x8708 -#define EQOS_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU -#define EQOS_WRAP_TSC_CAPTURE_LOW 0x8010U -#define EQOS_WRAP_TSC_CAPTURE_HIGH 0x8014U -#define EQOS_WRAP_PTP_CAPTURE_LOW 0x8018U -#define EQOS_WRAP_PTP_CAPTURE_HIGH 0x801CU - -/** @} */ - -/** - * @addtogroup HW Register BIT values - * - * @brief consists of corresponding EQOS MAC, MTL register bit values - * @{ - */ -/* Enable for DA-based or L2/L4 based DMA Channel selection*/ -#define EQOS_RXQ_TO_DMA_CHAN_MAP 0x03020100U -#define EQOS_RXQ_TO_DMA_CHAN_MAP1 0x07060504U -#define EQOS_RXQ_TO_DMA_CHAN_MAP_DCS_EN 0x13121110U -#define EQOS_RXQ_TO_DMA_CHAN_MAP1_DCS_EN 0x17161514U -#define EQOS_PAD_AUTO_CAL_CFG_ENABLE OSI_BIT(29) -#define EQOS_PAD_AUTO_CAL_CFG_START OSI_BIT(31) -#define EQOS_PAD_AUTO_CAL_STAT_ACTIVE OSI_BIT(31) -#define EQOS_PAD_CRTL_E_INPUT_OR_E_PWRD OSI_BIT(31) -#define EQOS_MCR_IPG_MASK 0x7000000U -#define EQOS_MCR_IPG_SHIFT 24U -#define EQOS_MCR_IPG 0x7U -#define EQOS_MCR_IPC OSI_BIT(27) -#define EQOS_MMC_CNTRL_CNTRST OSI_BIT(0) -#define EQOS_MMC_CNTRL_RSTONRD OSI_BIT(2) -#define EQOS_MMC_CNTRL_CNTPRST OSI_BIT(4) -#define EQOS_MMC_CNTRL_CNTPRSTLVL OSI_BIT(5) -#define EQOS_MTL_QTOMR_FTQ OSI_BIT(0) -#define EQOS_MTL_TSF OSI_BIT(1) -#define EQOS_MTL_TXQEN OSI_BIT(3) -#define EQOS_MTL_RSF OSI_BIT(5) -#define EQOS_MCR_RE OSI_BIT(0) -#define EQOS_MCR_TE OSI_BIT(1) -#define EQOS_MCR_DO OSI_BIT(10) -#define EQOS_MCR_DM OSI_BIT(13) -#define EQOS_MCR_FES OSI_BIT(14) -#define EQOS_MCR_PS OSI_BIT(15) -#define EQOS_MCR_JE OSI_BIT(16) -#define EQOS_MCR_JD OSI_BIT(17) -#define EQOS_MCR_WD OSI_BIT(19) -#define EQOS_MCR_ACS OSI_BIT(20) -#define EQOS_MCR_CST OSI_BIT(21) -#define EQOS_MCR_GPSLCE OSI_BIT(23) -#define EQOS_IMR_RGSMIIIE OSI_BIT(0) -#define EQOS_IMR_PCSLCHGIE OSI_BIT(1) -#define EQOS_IMR_PCSANCIE OSI_BIT(2) -#define EQOS_IMR_PMTIE OSI_BIT(4) -#define EQOS_IMR_LPIIE OSI_BIT(5) -#define EQOS_IMR_TXESIE OSI_BIT(13) -#define EQOS_IMR_FPEIE OSI_BIT(17) -#define EQOS_MAC_PCS_LNKSTS OSI_BIT(19) -#define EQOS_MAC_PCS_LNKMOD OSI_BIT(16) -#define EQOS_MAC_PCS_LNKSPEED (OSI_BIT(17) | OSI_BIT(18)) -#define EQOS_MAC_PCS_LNKSPEED_10 0x0U -#define EQOS_MAC_PCS_LNKSPEED_100 OSI_BIT(17) -#define EQOS_MAC_PCS_LNKSPEED_1000 OSI_BIT(18) -#define EQOS_MAC_VLANTIR_VLTI OSI_BIT(20) -#define EQOS_MAC_VLANTR_EVLS_ALWAYS_STRIP ((nveu32_t)0x3 << 21U) -#define EQOS_MAC_VLANTR_EVLRXS OSI_BIT(24) -#define EQOS_MAC_VLANTR_DOVLTC OSI_BIT(20) -#define EQOS_MAC_VLANTR_ERIVLT OSI_BIT(27) -#define EQOS_MAC_VLANTIRR_CSVL OSI_BIT(19) -#define EQOS_MAC_DEBUG_RPESTS OSI_BIT(0) -#define EQOS_MAC_DEBUG_TPESTS OSI_BIT(16) -#define EQOS_DMA_SBUS_BLEN8 OSI_BIT(2) -#define EQOS_DMA_SBUS_BLEN16 OSI_BIT(3) -#define EQOS_DMA_SBUS_EAME OSI_BIT(11) -#define EQOS_DMA_BMR_SWR OSI_BIT(0) -#define EQOS_DMA_BMR_DPSW OSI_BIT(8) -#define EQOS_MAC_RQC1R_TPQC (OSI_BIT(22) | OSI_BIT(23)) -#define EQOS_MAC_RQC1R_TPQC0 OSI_BIT(22) -#define EQOS_MAC_RQC1R_MCBCQ (OSI_BIT(18) | OSI_BIT(17) |\ - OSI_BIT(16)) -#define EQOS_MAC_RQC1R_MCBCQ_SHIFT 16U -#define EQOS_MAC_RQC1R_MCBCQ3 0x3U -#define EQOS_MAC_RQC1R_MCBCQ7 0x7U -#define EQOS_MAC_RQC1R_MCBCQEN OSI_BIT(20) - -#define EQOS_MAC_RQC1R_FPRQ (OSI_BIT(26) | OSI_BIT(25) | \ - OSI_BIT(24)) -#define EQOS_MAC_RQC1R_FPRQ_SHIFT 24U -#define EQOS_MAC_RQC1R_PTPQ (OSI_BIT(6) | OSI_BIT(5) | \ - OSI_BIT(4)) -#define EQOS_MAC_RQC1R_OMCBCQ OSI_BIT(28) -#define EQOS_MAC_RQC1R_PTPQ_SHIFT 4U -#define EQOS_MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ - OSI_BIT(1) | OSI_BIT(0)) -#define EQOS_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) -#define EQOS_DMA_ISR_MTLIS OSI_BIT(16) -#define EQOS_DMA_ISR_MACIS OSI_BIT(17) -#define EQOS_DMA_ISR_TXSTSIS OSI_BIT(13) -#define EQOS_MAC_ISR_RGSMIIS OSI_BIT(0) -#define EQOS_MAC_IMR_FPEIS OSI_BIT(17) -#define EQOS_MTL_TXQ_QW_ISCQW OSI_BIT(4) -#define EQOS_DMA_SBUS_RD_OSR_LMT 0x001F0000U -#define EQOS_DMA_SBUS_WR_OSR_LMT 0x1F000000U -#define EQOS_MTL_TXQ_SIZE_SHIFT 16U -#define EQOS_MTL_RXQ_SIZE_SHIFT 20U -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAC_ENABLE_LM OSI_BIT(12) -#define EQOS_MAC_VLANTIRR_VLTI OSI_BIT(20) -#define EQOS_DMA_SBUS_BLEN4 OSI_BIT(1) -#define EQOS_IMR_LPIIE OSI_BIT(5) -#define EQOS_IMR_PCSLCHGIE OSI_BIT(1) -#define EQOS_IMR_PCSANCIE OSI_BIT(2) -#define EQOS_IMR_PMTIE OSI_BIT(4) -#define EQOS_MAC_ISR_LPIIS OSI_BIT(5) -#define EQOS_MAC_LPI_CSR_LPITE OSI_BIT(20) -#define EQOS_MAC_LPI_CSR_LPITXA OSI_BIT(19) -#define EQOS_MAC_LPI_CSR_PLS OSI_BIT(17) -#define EQOS_MAC_LPI_CSR_LPIEN OSI_BIT(16) -#define EQOS_MCR_ARPEN OSI_BIT(31) -#define EQOS_RX_CLK_SEL OSI_BIT(8) -#define EQOS_MTL_TXQ_ETS_SSCR_SSC_MASK 0x00003FFFU -#define EQOS_MTL_TXQ_ETS_QW_ISCQW_MASK 0x000FFFFFU -#define EQOS_MTL_TXQ_ETS_HCR_HC_MASK 0x1FFFFFFFU -#define EQOS_MTL_TXQ_ETS_LCR_LC_MASK 0x1FFFFFFFU -#define EQOS_MTL_TXQ_ETS_CR_SLC_MASK (OSI_BIT(6) | OSI_BIT(5) | \ - OSI_BIT(4)) -#define EQOS_MTL_TXQ_ETS_CR_CC OSI_BIT(3) -#define EQOS_MTL_TXQ_ETS_CR_AVALG OSI_BIT(2) -#define EQOS_MTL_TXQ_ETS_CR_CC_SHIFT 3U -#define EQOS_MTL_TXQ_ETS_CR_AVALG_SHIFT 2U -#define EQOS_MTL_TXQEN_MASK (OSI_BIT(3) | OSI_BIT(2)) -#define EQOS_MTL_TXQEN_MASK_SHIFT 2U -#define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) -#define EQOS_MAC_VLAN_TR 0x0050U -#define EQOS_MAC_VLAN_TFR 0x0054U -#define EQOS_MAC_VLAN_HTR 0x0058U -#define EQOS_MAC_VLAN_TR_ETV OSI_BIT(16) -#define EQOS_MAC_VLAN_TR_VTIM OSI_BIT(17) -#define EQOS_MAC_VLAN_TR_VTIM_SHIFT 17 -#define EQOS_MAC_VLAN_TR_VTHM OSI_BIT(25) -#define EQOS_MAC_VLAN_TR_VL 0xFFFFU -#define EQOS_MAC_VLAN_HTR_VLHT 0xFFFFU -#define EQOS_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU -#define EQOS_MAC_VLAN_TR_ETV_SHIFT 16U -#define EQOS_MAC_PFR_HUC OSI_BIT(1) -#define EQOS_MAC_PFR_HMC OSI_BIT(2) -#define EQOS_MAC_MAX_HTR_REG_LEN 8U -#define EQOS_MAC_L3L4_CTR_L3HSBM0 (OSI_BIT(6) | OSI_BIT(7) | \ - OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10)) -#define EQOS_MAC_L3L4_CTR_L3HDBM0 (OSI_BIT(11) | OSI_BIT(12) | \ - OSI_BIT(13) | OSI_BIT(14) | \ - OSI_BIT(15)) -#define EQOS_MAC_PFR_SHIFT 16 -#define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) -#define EQOS_MTL_OP_MODE_FRPE OSI_BIT(15) -#define EQOS_MTL_OP_MODE_DTXSTS OSI_BIT(1) -#define EQOS_MAC_EXTR_PDC OSI_BIT(19) -#define EQOS_MTL_TXQ_DEBUG_TRCSTS 0x6U -#define EQOS_MTL_TXQ_DEBUG_TXQSTS OSI_BIT(4) -#define EQOS_MTL_RXQ_DEBUG_PRXQ 0x3FFF0000U -#define EQOS_MTL_RXQ_DEBUG_RXQSTS 0x30U -#define EQOS_MAC_EXTR_DCRCC OSI_BIT(16) -#define EQOS_MAC_EXTR_EIPGEN OSI_BIT(24) -#define EQOS_MAC_EXTR_EIPG_MASK 0x3E000000U -#define EQOS_MAC_EXTR_EIPG_SHIFT 25U -#define EQOS_MAC_EXTR_EIPG 0x3U -#endif /* !OSI_STRIPPED_LIB */ -#define EQOS_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) -#define EQOS_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) -#define EQOS_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) -#define EQOS_MAC_PAUSE_TIME 0xFFFF0000U -#define EQOS_MAC_PAUSE_TIME_MASK 0xFFFF0000U -#define EQOS_MTL_RXQ_OP_MODE_EHFC OSI_BIT(7) -#define EQOS_MTL_RXQ_OP_MODE_RFA_SHIFT 8U -#define EQOS_MTL_RXQ_OP_MODE_RFA_MASK 0x00003F00U -#define EQOS_MTL_RXQ_OP_MODE_RFD_SHIFT 14U -#define EQOS_MTL_RXQ_OP_MODE_RFD_MASK 0x000FC000U -#define EQOS_MAC_PFR_PR OSI_BIT(0) -#define EQOS_MAC_PFR_DAIF OSI_BIT(3) -#define EQOS_MAC_PFR_PM OSI_BIT(4) -#define EQOS_MAC_PFR_DBF OSI_BIT(5) -#define EQOS_MAC_PFR_PCF (OSI_BIT(6) | OSI_BIT(7)) -#define EQOS_MAC_PFR_SAIF OSI_BIT(8) -#define EQOS_MAC_PFR_SAF OSI_BIT(9) -#define EQOS_MAC_PFR_HPF OSI_BIT(10) -#define EQOS_MAC_PFR_VTFE OSI_BIT(16) -#define EQOS_MAC_PFR_IPFE OSI_BIT(20) -#define EQOS_MAC_PFR_IPFE_SHIFT 20U -#define EQOS_MAC_PFR_DNTU OSI_BIT(21) -#define EQOS_MAC_PFR_RA OSI_BIT(31) -#define EQOS_MAC_L4_SP_MASK 0x0000FFFFU -#define EQOS_MAC_L4_DP_MASK 0xFFFF0000U -#define EQOS_MAC_L4_DP_SHIFT 16 -#define EQOS_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18) -#define EQOS_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) -#define EQOS_MAC_L3L4_CTR_L4SPI_SHIFT 19 -#define EQOS_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20) -#define EQOS_MAC_L3L4_CTR_L4DPIM0 OSI_BIT(21) -#define EQOS_MAC_L3L4_CTR_L4DPI_SHIFT 21 -#define EQOS_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) -#define EQOS_MAC_L3L4_CTR_L4PEN0_SHIFT 16 -#define EQOS_MAC_L3L4_CTR_L3PEN0 OSI_BIT(0) -#define EQOS_MAC_L3L4_CTR_L3SAM0 OSI_BIT(2) -#define EQOS_MAC_L3L4_CTR_L3SAIM0 OSI_BIT(3) -#define EQOS_MAC_L3L4_CTR_L3SAI_SHIFT 3 -#define EQOS_MAC_L3L4_CTR_L3DAM0 OSI_BIT(4) -#define EQOS_MAC_L3L4_CTR_L3DAIM0 OSI_BIT(5) -#define EQOS_MAC_L3L4_CTR_L3DAI_SHIFT 5 -#define EQOS_MAC_L3L4_CTR_DMCHEN0 OSI_BIT(28) -#define EQOS_MAC_L3L4_CTR_DMCHEN0_SHIFT 28 -#define EQOS_MAC_L3L4_CTR_DMCHN0 (OSI_BIT(24) | OSI_BIT(25) | \ - OSI_BIT(26) | OSI_BIT(27)) -#define EQOS_MAC_L3L4_CTR_DMCHN0_SHIFT 24 -#define EQOS_MAC_L3_IP6_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \ - EQOS_MAC_L3L4_CTR_L3SAIM0 | \ - EQOS_MAC_L3L4_CTR_L3DAM0 | \ - EQOS_MAC_L3L4_CTR_L3DAIM0 | \ - EQOS_MAC_L3L4_CTR_DMCHEN0 | \ - EQOS_MAC_L3L4_CTR_DMCHN0) -#define EQOS_MAC_L3_IP4_SA_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3SAM0 | \ - EQOS_MAC_L3L4_CTR_L3SAIM0 | \ - EQOS_MAC_L3L4_CTR_DMCHEN0 | \ - EQOS_MAC_L3L4_CTR_DMCHN0) -#define EQOS_MAC_L3_IP4_DA_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L3DAM0 | \ - EQOS_MAC_L3L4_CTR_L3DAIM0 | \ - EQOS_MAC_L3L4_CTR_DMCHEN0 | \ - EQOS_MAC_L3L4_CTR_DMCHN0) -#define EQOS_MAC_L4_SP_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L4SPM0 | \ - EQOS_MAC_L3L4_CTR_L4SPIM0 | \ - EQOS_MAC_L3L4_CTR_DMCHEN0 | \ - EQOS_MAC_L3L4_CTR_DMCHN0) -#define EQOS_MAC_L4_DP_CTRL_CLEAR (EQOS_MAC_L3L4_CTR_L4DPM0 | \ - EQOS_MAC_L3L4_CTR_L4DPIM0 | \ - EQOS_MAC_L3L4_CTR_DMCHEN0 | \ - EQOS_MAC_L3L4_CTR_DMCHN0) -#define EQOS_MAC_L3L4_CTRL_ALL (EQOS_MAC_L3_IP6_CTRL_CLEAR | \ - EQOS_MAC_L3_IP4_SA_CTRL_CLEAR | \ - EQOS_MAC_L3_IP4_DA_CTRL_CLEAR | \ - EQOS_MAC_L4_SP_CTRL_CLEAR | \ - EQOS_MAC_L4_DP_CTRL_CLEAR) -#define EQOS_MAC_ADDRH_DCS (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define EQOS_MAC_ADDRH_DCS_SHIFT 16 -#define EQOS_MAC_ADDRH_MBC (OSI_BIT(29) | OSI_BIT(28) | \ - OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define EQOS_MAC_ADDRH_MBC_SHIFT 24 -#define EQOS_MAX_MASK_BYTE 0x3FU -#define EQOS_MAX_MAC_ADDR_REG 32U -#define EQOS_MAC_ADDRH_SA OSI_BIT(30) -#define EQOS_MAC_ADDRH_SA_SHIFT 30 -#define EQOS_MAC_ADDRH_AE OSI_BIT(31) -#define EQOS_MAC_RQC2_PSRQ_MASK ((nveu32_t)0xFF) -#define EQOS_MAC_RQC2_PSRQ_SHIFT 8U -#define EQOS_MAC_VLAN_TR_ETV_SHIFT 16U -#define EQOS_MAC_MAX_HTR_REG_LEN 8U -#define EQOS_MAC_TCR_TSENMACADDR OSI_BIT(18) -#define EQOS_MAC_TCR_SNAPTYPSEL_SHIFT 16U -#define EQOS_MAC_TCR_TSCTRLSSR OSI_BIT(9) -#define EQOS_MAC_TCR_TSADDREG OSI_BIT(5) -#define EQOS_MAC_TCR_TSINIT OSI_BIT(2) -#define EQOS_MAC_TCR_TSUPDT OSI_BIT(3) -#define EQOS_MAC_TCR_TSCFUPDT OSI_BIT(1) -#define EQOS_MAC_PTO_CR_DN (OSI_BIT(15) | OSI_BIT(14) | \ - OSI_BIT(13) | OSI_BIT(12) | \ - OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define EQOS_MAC_PTO_CR_DN_SHIFT 8U -#define EQOS_MAC_PTO_CR_APDREQEN OSI_BIT(2) -#define EQOS_MAC_PTO_CR_ASYNCEN OSI_BIT(1) -#define EQOS_MAC_PTO_CR_PTOEN OSI_BIT(0) -#define EQOS_MAC_PIDR_PID_MASK 0XFFFFU -#define EQOS_MAC_STNSUR_ADDSUB_SHIFT 31U -#define EQOS_MAC_SSIR_SSINC_SHIFT 16U -#define EQOS_MAC_GMIIDR_GD_WR_MASK 0xFFFF0000U -#define EQOS_MAC_GMIIDR_GD_MASK 0xFFFFU -#define EQOS_MDIO_PHY_ADDR_SHIFT 21U -#define EQOS_MDIO_PHY_REG_SHIFT 16U -#define EQOS_MDIO_PHY_REG_CR_SHIF 8U -#define EQOS_MDIO_PHY_REG_WRITE OSI_BIT(2) -#define EQOS_MDIO_PHY_REG_GOC_READ (OSI_BIT(2) | OSI_BIT(3)) -#define EQOS_MDIO_PHY_REG_SKAP OSI_BIT(4) -#define EQOS_MDIO_PHY_REG_C45E OSI_BIT(1) -#define EQOS_MAC_GMII_BUSY 0x00000001U -#define EQOS_MAC_EXTR_GPSL_MSK 0x00003FFFU -#define EQOS_MDIO_DATA_REG_PHYREG_MASK 0xFFFFU -#define EQOS_MDIO_DATA_REG_PHYREG_SHIFT 16U -#define EQOS_MDIO_DATA_REG_DEV_ADDR_MASK 0x1FU -#define EQOS_MDIO_DATA_REG_DEV_ADDR_SHIFT 16U - -#define EQOS_DMA_CHAN_INTR_STATUS 0xFU -#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) - -#define EQOS_ASID_CTRL_SHIFT_24 24U -#define EQOS_ASID_CTRL_SHIFT_16 16U -#define EQOS_ASID_CTRL_SHIFT_8 8U - -#define TEGRA_SID_EQOS (nveu32_t)20 -#define TEGRA_SID_EQOS_CH3 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_24) -#define TEGRA_SID_EQOS_CH2 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_16) -#define TEGRA_SID_EQOS_CH1 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_8) -#define EQOS_AXI_ASID_CTRL_VAL ((TEGRA_SID_EQOS_CH3) |\ - (TEGRA_SID_EQOS_CH2) |\ - (TEGRA_SID_EQOS_CH1) |\ - (TEGRA_SID_EQOS)) -#define TEGRA_SID_EQOS_CH7 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_24) -#define TEGRA_SID_EQOS_CH6 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_16) -#define TEGRA_SID_EQOS_CH5 ((TEGRA_SID_EQOS) << EQOS_ASID_CTRL_SHIFT_8) -#define EQOS_AXI_ASID1_CTRL_VAL ((TEGRA_SID_EQOS_CH7) |\ - (TEGRA_SID_EQOS_CH6) |\ - (TEGRA_SID_EQOS_CH5) |\ - (TEGRA_SID_EQOS)) -#define EQOS_5_30_SID 0x3U -#define EQOS_5_30_SID_CH3 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_24) -#define EQOS_5_30_SID_CH2 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_16) -#define EQOS_5_30_SID_CH1 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_8) -#define EQOS_5_30_ASID_CTRL_VAL ((EQOS_5_30_SID_CH3) |\ - (EQOS_5_30_SID_CH2) |\ - (EQOS_5_30_SID_CH1) |\ - (EQOS_5_30_SID)) -#define EQOS_5_30_SID_CH7 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_24) -#define EQOS_5_30_SID_CH6 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_16) -#define EQOS_5_30_SID_CH5 ((EQOS_5_30_SID) << EQOS_ASID_CTRL_SHIFT_8) -#define EQOS_5_30_ASID1_CTRL_VAL ((EQOS_5_30_SID_CH7) |\ - (EQOS_5_30_SID_CH6) |\ - (EQOS_5_30_SID_CH5) |\ - (EQOS_5_30_SID)) -#define EQOS_MMC_INTR_DISABLE 0xFFFFFFFFU - -/* MAC FPE control/statusOSI_BITmap */ -#define EQOS_MAC_FPE_CTS_EFPE OSI_BIT(0) -#define EQOS_MAC_FPE_CTS_TRSP OSI_BIT(19) -#define EQOS_MAC_FPE_CTS_TVER OSI_BIT(18) -#define EQOS_MAC_FPE_CTS_RRSP OSI_BIT(17) -#define EQOS_MAC_FPE_CTS_RVER OSI_BIT(16) -#define EQOS_MAC_FPE_CTS_SVER OSI_BIT(1) -#define EQOS_MAC_FPE_CTS_SRSP OSI_BIT(2) - -/* MTL_FPE_CTRL_STS */ -#define EQOS_MTL_FPE_CTS_PEC (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11) | \ - OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15)) -#define EQOS_MTL_FPE_CTS_PEC_SHIFT 8U -#define EQOS_MTL_FPE_CTS_PEC_MAX_SHIFT 16U -/* MTL FPE adv registers */ -#define EQOS_MTL_FPE_ADV_HADV_MASK (0xFFFFU) -#define EQOS_MTL_FPE_ADV_HADV_VAL 100U -/* MTL_EST_CONTROL */ -#define EQOS_MTL_EST_CONTROL_PTOV (OSI_BIT(24) | OSI_BIT(25) | \ - OSI_BIT(26) | OSI_BIT(27) | \ - OSI_BIT(28) | OSI_BIT(29) | \ - OSI_BIT(30) | OSI_BIT(31)) -#define EQOS_MTL_EST_CONTROL_PTOV_SHIFT 24U -#define EQOS_MTL_EST_PTOV_RECOMMEND 32U -#define EQOS_MTL_EST_CONTROL_CTOV (OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15) | \ - OSI_BIT(16) | OSI_BIT(17) | \ - OSI_BIT(18) | OSI_BIT(19) | \ - OSI_BIT(20) | OSI_BIT(21) | \ - OSI_BIT(22) | OSI_BIT(23)) -#define EQOS_MTL_EST_CONTROL_CTOV_SHIFT 12U -#define EQOS_MTL_EST_CTOV_RECOMMEND 94U -#define EQOS_8PTP_CYCLE 40U -#ifdef MACSEC_SUPPORT -/* MACSEC Recommended value*/ -#define EQOS_MTL_EST_CTOV_MACSEC_RECOMMEND 758U -#endif /* MACSEC_SUPPORT */ -#define EQOS_MTL_EST_CONTROL_TILS (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10)) -#define EQOS_MTL_EST_CONTROL_LCSE (OSI_BIT(6) | OSI_BIT(5)) -#define EQOS_MTL_EST_CONTROL_LCSE_SHIFT 5U -#define EQOS_MTL_EST_CONTROL_LCSE_VAL 0U -#define EQOS_MTL_EST_CONTROL_DFBS OSI_BIT(5) -#define EQOS_MTL_EST_CONTROL_DDBF OSI_BIT(4) -#define EQOS_MTL_EST_CONTROL_QHLBF OSI_BIT(3) -#define EQOS_MTL_EST_CONTROL_SSWL OSI_BIT(1) -#define EQOS_MTL_EST_CONTROL_EEST OSI_BIT(0) -#define EQOS_MTL_EST_OVERHEAD_OVHD (OSI_BIT(5) | OSI_BIT(4) | \ - OSI_BIT(3) | OSI_BIT(2) | \ - OSI_BIT(1) | OSI_BIT(0)) -#define EQOS_MTL_EST_OVERHEAD_RECOMMEND 0x17U -/* EST GCL controlOSI_BITmap */ -#define EQOS_MTL_EST_ADDR_SHIFT 8U -#define EQOS_MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11) | \ - OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15) | \ - OSI_BIT(16) | OSI_BIT(17) | \ - OSI_BIT(18) | OSI_BIT(19)) -#define EQOS_MTL_EST_SRWO OSI_BIT(0) -#define EQOS_MTL_EST_GCRR OSI_BIT(2) -#define EQOS_MTL_EST_ERR0 OSI_BIT(20) -/* EST GCRA addresses */ -#define EQOS_MTL_EST_BTR_LOW ((unsigned int)0x0 << \ - EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_BTR_HIGH ((unsigned int)0x1 << \ - EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_LOW ((unsigned int)0x2 << \ - EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_HIGH ((unsigned int)0x3 << \ - EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_CTR_HIGH_MAX 0xFFU -#define EQOS_MTL_EST_TER ((unsigned int)0x4 << \ - EQOS_MTL_EST_ADDR_SHIFT) -#define EQOS_MTL_EST_LLR ((unsigned int)0x5 << \ - EQOS_MTL_EST_ADDR_SHIFT) -/*EST MTL interrupt STATUS and ERR*/ -#define EQOS_MTL_IS_ESTIS OSI_BIT(18) -/* MTL_EST_STATUS*/ -#define EQOS_MTL_EST_STATUS_CGCE OSI_BIT(4) -#define EQOS_MTL_EST_STATUS_HLBS OSI_BIT(3) -#define EQOS_MTL_EST_STATUS_HLBF OSI_BIT(2) -#define EQOS_MTL_EST_STATUS_BTRE OSI_BIT(1) -#define EQOS_MTL_EST_STATUS_SWLC OSI_BIT(0) -#define EQOS_MTL_EST_ITRE_CGCE OSI_BIT(4) -#define EQOS_MTL_EST_ITRE_IEHS OSI_BIT(3) -#define EQOS_MTL_EST_ITRE_IEHF OSI_BIT(2) -#define EQOS_MTL_EST_ITRE_IEBE OSI_BIT(1) -#define EQOS_MTL_EST_ITRE_IECC OSI_BIT(0) -/* EQOS RGMII Rx padctrl registers E_INPUT bit */ -#define EQOS_PADCTL_EQOS_E_INPUT OSI_BIT(6) - -/** @} */ - -void update_ehfc_rfa_rfd(nveu32_t rx_fifo, nveu32_t *value); - -/** - * @addtogroup EQOS-Safety-Register EQOS Safety Register Mask - * - * @brief EQOS HW register masks and index - * @{ - */ -#define EQOS_MAC_MCR_MASK 0xFFFFFF7FU -#define EQOS_MAC_PFR_MASK 0x803107FFU -#define EQOS_MAC_HTR_MASK 0xFFFFFFFFU -#define EQOS_MAC_QX_TXFC_MASK 0xFFFF00F2U -#define EQOS_MAC_RQC0R_MASK 0xFFU -#define EQOS_MAC_RQC1R_MASK 0xF77077U -#define EQOS_MAC_RQC2R_MASK 0xFFFFFFFFU -#define EQOS_MAC_IMR_MASK 0x67039U -#define EQOS_MAC_MA0HR_MASK 0xFFFFFU -#define EQOS_MAC_MA0LR_MASK 0xFFFFFFFFU -#define EQOS_MAC_TCR_MASK 0x1107FF03U -#define EQOS_MAC_SSIR_MASK 0xFFFF00U -#define EQOS_MAC_TAR_MASK 0xFFFFFFFFU -#define EQOS_RXQ_DMA_MAP0_MASK 0x13131313U -#define EQOS_RXQ_EN_MASK (OSI_BIT(0) | OSI_BIT(1)) -#define EQOS_MTL_TXQ_OP_MODE_MASK 0xFF007EU -#define EQOS_MTL_TXQ_QW_MASK 0x1FFFFFU -#define EQOS_MTL_RXQ_OP_MODE_MASK 0xFFFFFFBU -#define EQOS_PAD_AUTO_CAL_CFG_MASK 0x7FFFFFFFU -#define EQOS_DMA_SBUS_MASK 0xDF1F3CFFU - -/* To add new registers to validate,append at end of this list and increment - * EQOS_MAX_CORE_SAFETY_REGS. - * Using macro instead of enum due to misra error. - */ -#define EQOS_MAC_MCR_IDX 0U -#define EQOS_MAC_PFR_IDX 1U -#define EQOS_MAC_HTR0_IDX 2U -#define EQOS_MAC_HTR1_IDX 3U -#define EQOS_MAC_HTR2_IDX 4U -#define EQOS_MAC_HTR3_IDX 5U -#define EQOS_MAC_Q0_TXFC_IDX 6U -#define EQOS_MAC_RQC0R_IDX 7U -#define EQOS_MAC_RQC1R_IDX 8U -#define EQOS_MAC_RQC2R_IDX 9U -#define EQOS_MAC_IMR_IDX 10U -#define EQOS_MAC_MA0HR_IDX 11U -#define EQOS_MAC_MA0LR_IDX 12U -#define EQOS_MAC_TCR_IDX 13U -#define EQOS_MAC_SSIR_IDX 14U -#define EQOS_MAC_TAR_IDX 15U -#define EQOS_PAD_AUTO_CAL_CFG_IDX 16U -#define EQOS_MTL_RXQ_DMA_MAP0_IDX 17U -#define EQOS_MTL_CH0_TX_OP_MODE_IDX 18U -#define EQOS_MTL_CH1_TX_OP_MODE_IDX 19U -#define EQOS_MTL_CH2_TX_OP_MODE_IDX 20U -#define EQOS_MTL_CH3_TX_OP_MODE_IDX 21U -#define EQOS_MTL_CH4_TX_OP_MODE_IDX 22U -#define EQOS_MTL_CH5_TX_OP_MODE_IDX 23U -#define EQOS_MTL_CH6_TX_OP_MODE_IDX 24U -#define EQOS_MTL_CH7_TX_OP_MODE_IDX 25U -#define EQOS_MTL_TXQ0_QW_IDX 26U -#define EQOS_MTL_TXQ1_QW_IDX 27U -#define EQOS_MTL_TXQ2_QW_IDX 28U -#define EQOS_MTL_TXQ3_QW_IDX 29U -#define EQOS_MTL_TXQ4_QW_IDX 30U -#define EQOS_MTL_TXQ5_QW_IDX 31U -#define EQOS_MTL_TXQ6_QW_IDX 32U -#define EQOS_MTL_TXQ7_QW_IDX 33U -#define EQOS_MTL_CH0_RX_OP_MODE_IDX 34U -#define EQOS_MTL_CH1_RX_OP_MODE_IDX 35U -#define EQOS_MTL_CH2_RX_OP_MODE_IDX 36U -#define EQOS_MTL_CH3_RX_OP_MODE_IDX 37U -#define EQOS_MTL_CH4_RX_OP_MODE_IDX 38U -#define EQOS_MTL_CH5_RX_OP_MODE_IDX 39U -#define EQOS_MTL_CH6_RX_OP_MODE_IDX 40U -#define EQOS_MTL_CH7_RX_OP_MODE_IDX 41U -#define EQOS_MTL_CH8_RX_OP_MODE_IDX 42U -#define EQOS_DMA_SBUS_IDX 43U -#define EQOS_MTL_RXQ_DMA_MAP1_IDX 44U -#define EQOS_MAX_CORE_SAFETY_REGS 45U -/** @} */ - -/** - * @addtogroup EQOS-MTL FRP Indirect Access register defines - * - * @brief EQOS MTL register offsets - * @{ - */ -#define EQOS_MTL_FRP_READ_UDELAY 1U -#define EQOS_MTL_FRP_READ_RETRY 10000U - -/* FRP Control and Status register defines */ -#define EQOS_MTL_RXP_CS_RXPI OSI_BIT(31) -#define EQOS_MTL_RXP_CS_NPE (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define EQOS_MTL_RXP_CS_NPE_SHIFT 16U -#define EQOS_MTL_RXP_CS_NVE (OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4) | \ - OSI_BIT(3) | OSI_BIT(2) | \ - OSI_BIT(1) | OSI_BIT(0)) -/* FRP Interrupt Control and Status register */ -#define EQOS_MTL_RXP_INTR_CS_PDRFIE OSI_BIT(19) -#define EQOS_MTL_RXP_INTR_CS_FOOVIE OSI_BIT(18) -#define EQOS_MTL_RXP_INTR_CS_NPEOVIE OSI_BIT(17) -#define EQOS_MTL_RXP_INTR_CS_NVEOVIE OSI_BIT(16) -#define EQOS_MTL_RXP_INTR_CS_PDRFIS OSI_BIT(3) -#define EQOS_MTL_RXP_INTR_CS_FOOVIS OSI_BIT(2) -#define EQOS_MTL_RXP_INTR_CS_NPEOVIS OSI_BIT(1) -#define EQOS_MTL_RXP_INTR_CS_NVEOVIS OSI_BIT(0) -/* Indirect Instruction Table defines */ -#define EQOS_MTL_FRP_IE0(x) ((x) * 0x4U + 0x0U) -#define EQOS_MTL_FRP_IE1(x) ((x) * 0x4U + 0x1U) -#define EQOS_MTL_FRP_IE2(x) ((x) * 0x4U + 0x2U) -#define EQOS_MTL_FRP_IE3(x) ((x) * 0x4U + 0x3U) -#define EQOS_MTL_FRP_IE2_DCH (OSI_BIT(31) | OSI_BIT(30) | \ - OSI_BIT(29) | OSI_BIT(28) | \ - OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define EQOS_MTL_FRP_IE2_DCH_SHIFT 24U -#define EQOS_MTL_FRP_IE2_DCH_MASK 0xFFU -#define EQOS_MTL_FRP_IE2_OKI (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define EQOS_MTL_FRP_IE2_OKI_SHIFT 16U -#define EQOS_MTL_FRP_IE2_FO (OSI_BIT(13) | OSI_BIT(12) | \ - OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define EQOS_MTL_FRP_IE2_FO_SHIFT 8U -#define EQOS_MTL_FRP_IE2_NC OSI_BIT(3) -#define EQOS_MTL_FRP_IE2_IM OSI_BIT(2) -#define EQOS_MTL_FRP_IE2_RF OSI_BIT(1) -#define EQOS_MTL_FRP_IE2_AF OSI_BIT(0) -/* Indirect register defines */ -#define EQOS_MTL_RXP_IND_CS_BUSY OSI_BIT(31) -#define EQOS_MTL_RXP_IND_CS_RXPEIEC (OSI_BIT(22) | OSI_BIT(21)) -#define EQOS_MTL_RXP_IND_CS_RXPEIEE OSI_BIT(20) -#define EQOS_MTL_RXP_IND_CS_WRRDN OSI_BIT(16) -#define EQOS_MTL_RXP_IND_CS_ADDR (OSI_BIT(9) | OSI_BIT(8) | \ - OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4) | \ - OSI_BIT(3) | OSI_BIT(2) | \ - OSI_BIT(1) | OSI_BIT(0)) -/** @} */ - -/** - * @brief core_func_safety - Struct used to store last written values of - * critical core HW registers. - */ -struct core_func_safety { - /** Array of reg MMIO addresses (base of EQoS + offset of reg) */ - void *reg_addr[EQOS_MAX_CORE_SAFETY_REGS]; - /** Array of bit-mask value of each corresponding reg - * (used to ignore self-clearing/reserved bits in reg) */ - nveu32_t reg_mask[EQOS_MAX_CORE_SAFETY_REGS]; - /** Array of value stored in each corresponding register */ - nveu32_t reg_val[EQOS_MAX_CORE_SAFETY_REGS]; - /** OSI lock variable used to protect writes to reg while - * validation is in-progress */ - nveu32_t core_safety_lock; -}; - -/** - * @addtogroup EQOS_HW EQOS HW BACKUP registers - * - * @brief Definitions related to taking backup of EQOS core registers. - * @{ - */ - -/* Hardware Register offsets to be backed up during suspend. - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before EQOS_MAX_MAC_BAK_IDX, and - * update EQOS_MAX_MAC_BAK_IDX based on new macro. - */ -#define EQOS_MAC_MCR_BAK_IDX 0U -#define EQOS_MAC_EXTR_BAK_IDX ((EQOS_MAC_MCR_BAK_IDX + 1U)) -#define EQOS_MAC_PFR_BAK_IDX ((EQOS_MAC_EXTR_BAK_IDX + 1U)) -#define EQOS_MAC_VLAN_TAG_BAK_IDX ((EQOS_MAC_PFR_BAK_IDX + 1U)) -#define EQOS_MAC_VLANTIR_BAK_IDX ((EQOS_MAC_VLAN_TAG_BAK_IDX + 1U)) -#define EQOS_MAC_RX_FLW_CTRL_BAK_IDX ((EQOS_MAC_VLANTIR_BAK_IDX + 1U)) -#define EQOS_MAC_RQC0R_BAK_IDX ((EQOS_MAC_RX_FLW_CTRL_BAK_IDX + 1U)) -#define EQOS_MAC_RQC1R_BAK_IDX ((EQOS_MAC_RQC0R_BAK_IDX + 1U)) -#define EQOS_MAC_RQC2R_BAK_IDX ((EQOS_MAC_RQC1R_BAK_IDX + 1U)) -#define EQOS_MAC_ISR_BAK_IDX ((EQOS_MAC_RQC2R_BAK_IDX + 1U)) -#define EQOS_MAC_IMR_BAK_IDX ((EQOS_MAC_ISR_BAK_IDX + 1U)) -#define EQOS_MAC_PMTCSR_BAK_IDX ((EQOS_MAC_IMR_BAK_IDX + 1U)) -#define EQOS_MAC_LPI_CSR_BAK_IDX ((EQOS_MAC_PMTCSR_BAK_IDX + 1U)) -#define EQOS_MAC_LPI_TIMER_CTRL_BAK_IDX ((EQOS_MAC_LPI_CSR_BAK_IDX + 1U)) -#define EQOS_MAC_LPI_EN_TIMER_BAK_IDX ((EQOS_MAC_LPI_TIMER_CTRL_BAK_IDX + 1U)) -#define EQOS_MAC_ANS_BAK_IDX ((EQOS_MAC_LPI_EN_TIMER_BAK_IDX + 1U)) -#define EQOS_MAC_PCS_BAK_IDX ((EQOS_MAC_ANS_BAK_IDX + 1U)) -#define EQOS_5_00_MAC_ARPPA_BAK_IDX ((EQOS_MAC_PCS_BAK_IDX + 1U)) -#define EQOS_MMC_CNTRL_BAK_IDX ((EQOS_5_00_MAC_ARPPA_BAK_IDX + 1U)) -#define EQOS_4_10_MAC_ARPPA_BAK_IDX ((EQOS_MMC_CNTRL_BAK_IDX + 1U)) -#define EQOS_MAC_TCR_BAK_IDX ((EQOS_4_10_MAC_ARPPA_BAK_IDX + 1U)) -#define EQOS_MAC_SSIR_BAK_IDX ((EQOS_MAC_TCR_BAK_IDX + 1U)) -#define EQOS_MAC_STSR_BAK_IDX ((EQOS_MAC_SSIR_BAK_IDX + 1U)) -#define EQOS_MAC_STNSR_BAK_IDX ((EQOS_MAC_STSR_BAK_IDX + 1U)) -#define EQOS_MAC_STSUR_BAK_IDX ((EQOS_MAC_STNSR_BAK_IDX + 1U)) -#define EQOS_MAC_STNSUR_BAK_IDX ((EQOS_MAC_STSUR_BAK_IDX + 1U)) -#define EQOS_MAC_TAR_BAK_IDX ((EQOS_MAC_STNSUR_BAK_IDX + 1U)) -#define EQOS_DMA_BMR_BAK_IDX ((EQOS_MAC_TAR_BAK_IDX + 1U)) -#define EQOS_DMA_SBUS_BAK_IDX ((EQOS_DMA_BMR_BAK_IDX + 1U)) -#define EQOS_DMA_ISR_BAK_IDX ((EQOS_DMA_SBUS_BAK_IDX + 1U)) -#define EQOS_MTL_OP_MODE_BAK_IDX ((EQOS_DMA_ISR_BAK_IDX + 1U)) -#define EQOS_MTL_RXQ_DMA_MAP0_BAK_IDX ((EQOS_MTL_OP_MODE_BAK_IDX + 1U)) -/* x varies from 0-7, 8 HTR registers total */ -#define EQOS_MAC_HTR_REG_BAK_IDX(x) ((EQOS_MTL_RXQ_DMA_MAP0_BAK_IDX + 1U + \ - (x))) -/* x varies from 0-7, 8 queues total */ -#define EQOS_MAC_QX_TX_FLW_CTRL_BAK_IDX(x) ((EQOS_MAC_HTR_REG_BAK_IDX(0U) \ - + EQOS_MAX_HTR_REGS + (x))) -/* x varies from 0-127, 128 L2 DA/SA filters total */ -#define EQOS_MAC_ADDRH_BAK_IDX(x) ((EQOS_MAC_QX_TX_FLW_CTRL_BAK_IDX(0U) \ - + OSI_EQOS_MAX_NUM_QUEUES + (x))) -#define EQOS_MAC_ADDRL_BAK_IDX(x) ((EQOS_MAC_ADDRH_BAK_IDX(0U) + \ - EQOS_MAX_MAC_ADDRESS_FILTER + (x))) -/* x varies from 0-7, 8 L3/L4 filters total */ -#define EQOS_MAC_L3L4_CTR_BAK_IDX(x) ((EQOS_MAC_ADDRL_BAK_IDX(0U) + \ - EQOS_MAX_MAC_ADDRESS_FILTER + (x))) -#define EQOS_MAC_L4_ADR_BAK_IDX(x) ((EQOS_MAC_L3L4_CTR_BAK_IDX(0U) + \ - EQOS_MAX_L3_L4_FILTER + (x))) -#define EQOS_MAC_L3_AD0R_BAK_IDX(x) ((EQOS_MAC_L4_ADR_BAK_IDX(0U) + \ - EQOS_MAX_L3_L4_FILTER + (x))) -#define EQOS_MAC_L3_AD1R_BAK_IDX(x) ((EQOS_MAC_L3_AD0R_BAK_IDX(0U) + \ - EQOS_MAX_L3_L4_FILTER + (x))) -#define EQOS_MAC_L3_AD2R_BAK_IDX(x) ((EQOS_MAC_L3_AD1R_BAK_IDX(0U) + \ - EQOS_MAX_L3_L4_FILTER + (x))) -#define EQOS_MAC_L3_AD3R_BAK_IDX(x) ((EQOS_MAC_L3_AD2R_BAK_IDX(0U) + \ - EQOS_MAX_L3_L4_FILTER + (x))) - -/* MTL HW Register offsets - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before EQOS_MAX_MTL_BAK_IDX, and - * update EQOS_MAX_MTL_BAK_IDX based on new macro. - */ -/* x varies from 0-7, 8 queues total */ -#define EQOS_MTL_CHX_TX_OP_MODE_BAK_IDX(x) ((EQOS_MAC_L3_AD3R_BAK_IDX(0U) \ - + EQOS_MAX_L3_L4_FILTER + (x))) -#define EQOS_MTL_TXQ_ETS_CR_BAK_IDX(x) ((EQOS_MTL_CHX_TX_OP_MODE_BAK_IDX(0U) \ - + OSI_EQOS_MAX_NUM_QUEUES + (x))) -#define EQOS_MTL_TXQ_QW_BAK_IDX(x) ((EQOS_MTL_TXQ_ETS_CR_BAK_IDX(0U) + \ - OSI_EQOS_MAX_NUM_QUEUES + (x))) -#define EQOS_MTL_TXQ_ETS_SSCR_BAK_IDX(x) ((EQOS_MTL_TXQ_QW_BAK_IDX(0U) \ - + OSI_EQOS_MAX_NUM_QUEUES + \ - (x))) -#define EQOS_MTL_TXQ_ETS_HCR_BAK_IDX(x) ((EQOS_MTL_TXQ_ETS_SSCR_BAK_IDX(0U) + \ - OSI_EQOS_MAX_NUM_QUEUES + (x))) -#define EQOS_MTL_TXQ_ETS_LCR_BAK_IDX(x) ((EQOS_MTL_TXQ_ETS_HCR_BAK_IDX(0U) + \ - OSI_EQOS_MAX_NUM_QUEUES + (x))) -#define EQOS_MTL_CHX_RX_OP_MODE_BAK_IDX(x) \ - ((EQOS_MTL_TXQ_ETS_LCR_BAK_IDX(0U) + \ - OSI_EQOS_MAX_NUM_QUEUES + (x))) - -/* EQOS Wrapper register offsets to be saved during suspend - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before EQOS_MAX_WRAPPER_BAK_IDX, - * and update EQOS_MAX_WRAPPER_BAK_IDX based on new macro. - */ -#define EQOS_CLOCK_CTRL_0_BAK_IDX ((EQOS_MTL_CHX_RX_OP_MODE_BAK_IDX(0U) \ - + OSI_EQOS_MAX_NUM_QUEUES)) -#define EQOS_AXI_ASID_CTRL_BAK_IDX ((EQOS_CLOCK_CTRL_0_BAK_IDX + 1U)) -#define EQOS_PAD_CRTL_BAK_IDX ((EQOS_AXI_ASID_CTRL_BAK_IDX + 1U)) -#define EQOS_PAD_AUTO_CAL_CFG_BAK_IDX ((EQOS_PAD_CRTL_BAK_IDX + 1U)) -/* EQOS_PAD_AUTO_CAL_STAT is Read-only. Skip backup/restore */ - -/* To add new registers to backup during suspend, and restore during resume - * add it before this line, and increment EQOS_MAC_BAK_IDX accordingly. - */ - -#ifndef OSI_STRIPPED_LIB -#define EQOS_MAX_BAK_IDX ((EQOS_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) -#endif /* !OSI_STRIPPED_LIB */ -/** @} */ - -/** - * @addtogroup EQOS-MAC-Feature EQOS MAC HW feature registers bit fields - * - * @brief HW feature register bit masks and bit shifts. - * @{ - */ -#define EQOS_MAC_HFR0_MIISEL_MASK 0x1U -#define EQOS_MAC_HFR0_MIISEL_SHIFT 0U - -#define EQOS_MAC_HFR0_GMIISEL_MASK 0x1U -#define EQOS_MAC_HFR0_GMIISEL_SHIFT 1U - -#define EQOS_MAC_HFR0_HDSEL_MASK 0x1U -#define EQOS_MAC_HFR0_HDSEL_SHIFT 2U - -#define EQOS_MAC_HFR0_PCSSEL_MASK 0x1U -#define EQOS_MAC_HFR0_PCSSEL_SHIFT 3U - -#define EQOS_MAC_HFR0_VLHASH_MASK 0x1U -#define EQOS_MAC_HFR0_VLHASH_SHIFT 4U - -#define EQOS_MAC_HFR0_SMASEL_MASK 0x1U -#define EQOS_MAC_HFR0_SMASEL_SHIFT 5U - -#define EQOS_MAC_HFR0_RWKSEL_MASK 0x1U -#define EQOS_MAC_HFR0_RWKSEL_SHIFT 6U - -#define EQOS_MAC_HFR0_MGKSEL_MASK 0x1U -#define EQOS_MAC_HFR0_MGKSEL_SHIFT 7U - -#define EQOS_MAC_HFR0_MMCSEL_MASK 0x1U -#define EQOS_MAC_HFR0_MMCSEL_SHIFT 8U - -#define EQOS_MAC_HFR0_ARPOFFLDEN_MASK 0x1U -#define EQOS_MAC_HFR0_ARPOFFLDEN_SHIFT 9U - -#define EQOS_MAC_HFR0_TSSSEL_MASK 0x1U -#define EQOS_MAC_HFR0_TSSSEL_SHIFT 12U - -#define EQOS_MAC_HFR0_EEESEL_MASK 0x1U -#define EQOS_MAC_HFR0_EEESEL_SHIFT 13U - -#define EQOS_MAC_HFR0_TXCOESEL_MASK 0x1U -#define EQOS_MAC_HFR0_TXCOESEL_SHIFT 14U - -#define EQOS_MAC_HFR0_RXCOE_MASK 0x1U -#define EQOS_MAC_HFR0_RXCOE_SHIFT 16U - -#define EQOS_MAC_HFR0_ADDMACADRSEL_MASK 0x1FU -#define EQOS_MAC_HFR0_ADDMACADRSEL_SHIFT 18U - -#define EQOS_MAC_HFR0_MACADR32SEL_MASK 0x1U -#define EQOS_MAC_HFR0_MACADR32SEL_SHIFT 23U - -#define EQOS_MAC_HFR0_MACADR64SEL_MASK 0x1U -#define EQOS_MAC_HFR0_MACADR64SEL_SHIFT 24U - -#define EQOS_MAC_HFR0_TSINTSEL_MASK 0x3U -#define EQOS_MAC_HFR0_TSINTSEL_SHIFT 25U - -#define EQOS_MAC_HFR0_SAVLANINS_MASK 0x1U -#define EQOS_MAC_HFR0_SAVLANINS_SHIFT 27U - -#define EQOS_MAC_HFR0_ACTPHYSEL_MASK 0x7U -#define EQOS_MAC_HFR0_ACTPHYSEL_SHIFT 28U - -#define EQOS_MAC_HFR1_RXFIFOSIZE_MASK 0x1FU -#define EQOS_MAC_HFR1_RXFIFOSIZE_SHIFT 0U - -#define EQOS_MAC_HFR1_TXFIFOSIZE_MASK 0x1FU -#define EQOS_MAC_HFR1_TXFIFOSIZE_SHIFT 6U - -#define EQOS_MAC_HFR1_OSTEN_MASK 0x1U -#define EQOS_MAC_HFR1_OSTEN_SHIFT 11U - -#define EQOS_MAC_HFR1_PTOEN_MASK 0x1U -#define EQOS_MAC_HFR1_PTOEN_SHIFT 12U - -#define EQOS_MAC_HFR1_ADVTHWORD_MASK 0x1U -#define EQOS_MAC_HFR1_ADVTHWORD_SHIFT 13U - -#define EQOS_MAC_HFR1_ADDR64_MASK 0x3U -#define EQOS_MAC_HFR1_ADDR64_SHIFT 14U - -#define EQOS_MAC_HFR1_DCBEN_MASK 0x1U -#define EQOS_MAC_HFR1_DCBEN_SHIFT 16U - -#define EQOS_MAC_HFR1_SPHEN_MASK 0x1U -#define EQOS_MAC_HFR1_SPHEN_SHIFT 17U - -#define EQOS_MAC_HFR1_TSOEN_MASK 0x1U -#define EQOS_MAC_HFR1_TSOEN_SHIFT 18U - -#define EQOS_MAC_HFR1_DMADEBUGEN_MASK 0x1U -#define EQOS_MAC_HFR1_DMADEBUGEN_SHIFT 19U - -#define EQOS_MAC_HFR1_AVSEL_MASK 0x1U -#define EQOS_MAC_HFR1_AVSEL_SHIFT 20U - -#define EQOS_MAC_HFR1_RAVSEL_MASK 0x1U -#define EQOS_MAC_HFR1_RAVSEL_SHIFT 21U - -#define EQOS_MAC_HFR1_POUOST_MASK 0x1U -#define EQOS_MAC_HFR1_POUOST_SHIFT 23U - -#define EQOS_MAC_HFR1_HASHTBLSZ_MASK 0x3U -#define EQOS_MAC_HFR1_HASHTBLSZ_SHIFT 24U - -#define EQOS_MAC_HFR1_L3L4FILTERNUM_MASK 0xFU -#define EQOS_MAC_HFR1_L3L4FILTERNUM_SHIFT 27U - -#define EQOS_MAC_HFR2_RXQCNT_MASK 0xFU -#define EQOS_MAC_HFR2_RXQCNT_SHIFT 0U - -#define EQOS_MAC_HFR2_TXQCNT_MASK 0xFU -#define EQOS_MAC_HFR2_TXQCNT_SHIFT 6U - -#define EQOS_MAC_HFR2_RXCHCNT_MASK 0xFU -#define EQOS_MAC_HFR2_RXCHCNT_SHIFT 12U - -#define EQOS_MAC_HFR2_TXCHCNT_MASK 0xFU -#define EQOS_MAC_HFR2_TXCHCNT_SHIFT 18U - -#define EQOS_MAC_HFR2_PPSOUTNUM_MASK 0x7U -#define EQOS_MAC_HFR2_PPSOUTNUM_SHIFT 24U - -#define EQOS_MAC_HFR2_AUXSNAPNUM_MASK 0x7U -#define EQOS_MAC_HFR2_AUXSNAPNUM_SHIFT 28U - -#define EQOS_MAC_HFR3_NRVF_MASK 0x7U -#define EQOS_MAC_HFR3_NRVF_SHIFT 0U - -#define EQOS_MAC_HFR3_CBTISEL_MASK 0x1U -#define EQOS_MAC_HFR3_CBTISEL_SHIFT 4U - -#define EQOS_MAC_HFR3_DVLAN_MASK 0x1U -#define EQOS_MAC_HFR3_DVLAN_SHIFT 5U - -#define EQOS_MAC_HFR3_PDUPSEL_MASK 0x1U -#define EQOS_MAC_HFR3_PDUPSEL_SHIFT 9U - -#define EQOS_MAC_HFR3_FRPSEL_MASK 0x1U -#define EQOS_MAC_HFR3_FRPSEL_SHIFT 10U - -#define EQOS_MAC_HFR3_FRPPB_MASK 0x3U -#define EQOS_MAC_HFR3_FRPPB_SHIFT 11U - -#define EQOS_MAC_HFR3_FRPES_MASK 0x3U -#define EQOS_MAC_HFR3_FRPES_SHIFT 13U - -#define EQOS_MAC_HFR3_ESTSEL_MASK 0x1U -#define EQOS_MAC_HFR3_ESTSEL_SHIFT 16U - -#define EQOS_MAC_HFR3_GCLDEP_MASK 0x7U -#define EQOS_MAC_HFR3_GCLDEP_SHIFT 17U - -#define EQOS_MAC_HFR3_GCLWID_MASK 0x3U -#define EQOS_MAC_HFR3_GCLWID_SHIFT 20U - -#define EQOS_MAC_HFR3_FPESEL_MASK 0x1U -#define EQOS_MAC_HFR3_FPESEL_SHIFT 26U - -#define EQOS_MAC_HFR3_TBSSEL_MASK 0x1U -#define EQOS_MAC_HFR3_TBSSEL_SHIFT 27U - -#define EQOS_MAC_HFR3_ASP_MASK 0x3U -#define EQOS_MAC_HFR3_ASP_SHIFT 28U -/** @} */ - -/** - * @addtogroup EQOS-MAC EQOS MAC HW supported features - * - * @brief Helps in identifying the features that are set in MAC HW - * @{ - */ -#define EQOS_MAC_HFR0 0x11C -#define EQOS_MAC_HFR1 0x120 -#define EQOS_MAC_HFR2 0x124 -#define EQOS_MAC_HFR3 0x128 -/** @} */ - -#ifdef HSI_SUPPORT -/** - * @addtogroup EQOS-HSI - * - * @brief EQOS HSI related registers and bitmap - * @{ - */ -#define EQOS_MTL_ECC_INTERRUPT_ENABLE 0xCC8U -#define EQOS_MTL_TXCEIE OSI_BIT(0) -#define EQOS_MTL_RXCEIE OSI_BIT(4) -#define EQOS_MTL_ECEIE OSI_BIT(8) -#define EQOS_MTL_RPCEIE OSI_BIT(12) -#define EQOS_DMA_ECC_INTERRUPT_ENABLE 0x1084U -#define EQOS_DMA_TCEIE OSI_BIT(0) -#define EQOS_DMA_DCEIE OSI_BIT(1) -#define EQOS_MTL_ECC_INTERRUPT_STATUS 0xCCCU -#define EQOS_DMA_ECC_INTERRUPT_STATUS 0x1088U -#define EQOS_MTL_ECC_CONTROL 0xCC0U -#define EQOS_MTL_ECC_MTXEE OSI_BIT(0) -#define EQOS_MTL_ECC_MRXEE OSI_BIT(1) -#define EQOS_MTL_ECC_MESTEE OSI_BIT(2) -#define EQOS_MTL_ECC_MRXPEE OSI_BIT(3) -#define EQOS_MTL_ECC_TSOEE OSI_BIT(4) -#define EQOS_MTL_ECC_DSCEE OSI_BIT(5) -#define EQOS_MAC_FSM_ACT_TIMER 0x014CU -#define EQOS_LTMRMD_SHIFT 20U -#define EQOS_LTMRMD_MASK 0xF00000U -#define EQOS_NTMRMD_SHIFT 16U -#define EQOS_NTMRMD_MASK 0xF0000U -#define EQOS_TMR_SHIFT 0U -#define EQOS_TMR_MASK 0x3FFU -#define EQOS_MAC_FSM_CONTROL 0x148U -#define EQOS_TMOUTEN OSI_BIT(0) -#define EQOS_PRTYEN OSI_BIT(1) -#define EQOS_MAC_DPP_FSM_INTERRUPT_STATUS 0x140U -#define EQOS_MTL_DPP_CONTROL 0xCE0U -#define EQOS_EDPP OSI_BIT(0) -#define EQOS_MAC_DPP_FSM_INTERRUPT_STATUS 0x140U -/** @} */ -#endif - -#endif /* INCLUDED_EQOS_CORE_H */ diff --git a/osi/core/eqos_mmc.c b/osi/core/eqos_mmc.c deleted file mode 100644 index e0de057..0000000 --- a/osi/core/eqos_mmc.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (c) 2018-2021, 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 "../osi/common/common.h" -#include -#include "eqos_mmc.h" -#include "eqos_core.h" - -/** - * @brief update_mmc_val - function to read register and return value to callee - * - * @note - * Algorithm: - * - Read the registers, check for boundary, if more, reset - * counters else return same to caller. - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] last_value: previous value of stats variable. - * @param[in] offset: HW register offset - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static inline nveu64_t update_mmc_val(struct osi_core_priv_data *const osi_core, - nveu64_t last_value, - nveu64_t offset) -{ - nveu64_t temp; - nveu32_t value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + offset); - - temp = last_value + value; - if (temp < last_value) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_OUTOFBOUND, - "Value overflow resetting all counters\n", - (nveul64_t)offset); - eqos_reset_mmc(osi_core); - } else { - return temp; - } - - return 0; -} - -/** - * @brief eqos_reset_mmc - To reset MMC registers and ether_mmc_counter - * structure variable - * - * @param[in, out] osi_core: OSI core private data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void eqos_reset_mmc(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - /* self-clear bit in one clock cycle */ - value |= EQOS_MMC_CNTRL_CNTRST; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + EQOS_MMC_CNTRL); - osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); -} - -/** - * @brief eqos_read_mmc - To read MMC registers and ether_mmc_counter structure - * variable - * - * @note - * Algorithm: - * - Read corresponding register value of #osi_core_priv_data->mmc(#osi_mmc_counters) - * member and increment its value. - * - If any counter overflows, reset all Sw counters and reset HW counter register. - * - * @param[in, out] osi_core: OSI core private data structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - osi_core->osd should be populated - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void eqos_read_mmc(struct osi_core_priv_data *const 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_tx_lpi_usec_cntr = - update_mmc_val(osi_core, mmc->mmc_tx_lpi_usec_cntr, - MMC_TXLPIUSECCNTR); - mmc->mmc_tx_lpi_tran_cntr = - update_mmc_val(osi_core, mmc->mmc_tx_lpi_tran_cntr, - MMC_TXLPITRANCNTR); - mmc->mmc_rx_lpi_usec_cntr = - update_mmc_val(osi_core, mmc->mmc_rx_lpi_usec_cntr, - MMC_RXLPIUSECCNTR); - mmc->mmc_rx_lpi_tran_cntr = - update_mmc_val(osi_core, mmc->mmc_rx_lpi_tran_cntr, - MMC_RXLPITRANCNTR); - 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 = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd, - MMC_RXIPV6_GD_PKTS); - mmc->mmc_rx_ipv6_hderr = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, - MMC_RXIPV6_HDRERR_PKTS); - mmc->mmc_rx_ipv6_nopay = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay, - 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_RXUDP_GD_OCTETS); - mmc->mmc_rx_ipv6_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets, - MMC_RXIPV6_GD_OCTETS); - mmc->mmc_rx_ipv6_hderr_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets, - MMC_RXIPV6_HDRERR_OCTETS); - mmc->mmc_rx_ipv6_nopay_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets, - 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); - mmc->mmc_tx_fpe_frag_cnt = - update_mmc_val(osi_core, mmc->mmc_tx_fpe_frag_cnt, - MMC_TX_FPE_FRAG_COUNTER); - mmc->mmc_tx_fpe_hold_req_cnt = - update_mmc_val(osi_core, mmc->mmc_tx_fpe_hold_req_cnt, - MMC_TX_HOLD_REQ_COUNTER); - mmc->mmc_rx_packet_reass_err_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_reass_err_cnt, - MMC_RX_PKT_ASSEMBLY_ERR_CNTR); - mmc->mmc_rx_packet_smd_err_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_smd_err_cnt, - MMC_RX_PKT_SMD_ERR_CNTR); - mmc->mmc_rx_packet_asm_ok_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_asm_ok_cnt, - MMC_RX_PKT_ASSEMBLY_OK_CNTR); - mmc->mmc_rx_fpe_fragment_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_fpe_fragment_cnt, - MMC_RX_FPE_FRAG_CNTR); -} diff --git a/osi/core/eqos_mmc.h b/osi/core/eqos_mmc.h deleted file mode 100644 index 8021e0b..0000000 --- a/osi/core/eqos_mmc.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2018-2020, 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 INCLUDED_EQOS_MMC_H -#define INCLUDED_EQOS_MMC_H - -/** - * @addtogroup EQOS-MMC MMC HW register offsets - * - * @brief MMC HW register offsets - * @{ - */ -#define MMC_TXOCTETCOUNT_GB 0x00714U -#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_TXLPIUSECCNTR 0x007ec -#define MMC_TXLPITRANCNTR 0x007f0 -#define MMC_RXLPIUSECCNTR 0x007f4 -#define MMC_RXLPITRANCNTR 0x007f8 -#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 -#define MMC_TX_FPE_FRAG_COUNTER 0x008A8 -#define MMC_TX_HOLD_REQ_COUNTER 0x008AC -#define MMC_RX_PKT_ASSEMBLY_ERR_CNTR 0x008C8 -#define MMC_RX_PKT_SMD_ERR_CNTR 0x008CC -#define MMC_RX_PKT_ASSEMBLY_OK_CNTR 0x008D0 -#define MMC_RX_FPE_FRAG_CNTR 0x008D4 -/** @} */ - -void eqos_read_mmc(struct osi_core_priv_data *const osi_core); -void eqos_reset_mmc(struct osi_core_priv_data *const osi_core); -#endif /* INCLUDED_EQOS_MMC_H */ diff --git a/osi/core/frp.c b/osi/core/frp.c deleted file mode 100644 index 4b0c953..0000000 --- a/osi/core/frp.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "../osi/common/common.h" -#include "frp.h" - -/** - * @brief frp_entry_copy - Copy FRP entry - * - * Algorithm: Copy source FRP entry data into destination entry - * - * @param[in] dst: Destination FRP entry pointer. - * @param[in] src: source FRP entry pointer. - * - */ -static void frp_entry_copy(struct osi_core_frp_entry *dst, - struct osi_core_frp_entry *src) -{ - dst->frp_id = src->frp_id; - dst->data.match_data = src->data.match_data; - dst->data.match_en = src->data.match_en; - dst->data.accept_frame = src->data.accept_frame; - dst->data.reject_frame = src->data.reject_frame; - dst->data.inverse_match = src->data.inverse_match; - dst->data.next_ins_ctrl = src->data.next_ins_ctrl; - dst->data.frame_offset = src->data.frame_offset; - dst->data.ok_index = src->data.ok_index; - dst->data.dma_chsel = src->data.dma_chsel; -} - -/** - * @brief frp_entry_find - Find FRP entry in table - * - * Algorithm: Parse FRP table for given ID and bookmark - * start position and count of entries for a given ID. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] frp_id: FRP ID to find. - * @param[out] start: Pointer to store start index for given frp_id. - * @param[out] no_entries: No of FRP index's used for given frp_id. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_entry_find(struct osi_core_priv_data *const osi_core, - int frp_id, - unsigned char *start, - unsigned char *no_entries) -{ - unsigned char count = OSI_NONE, found = OSI_NONE; - struct osi_core_frp_entry *entry = OSI_NULL; - - /* Parse the FRP table for give frp_id */ - for (count = 0U; count < osi_core->frp_cnt; count++) { - entry = &osi_core->frp_table[count]; - if (entry->frp_id == frp_id) { - /* Entry found break */ - if (found == OSI_NONE) { - *start = count; - *no_entries = 1; - found = OSI_ENABLE; - } else { - /* Increment entries */ - *no_entries = (unsigned char) (*no_entries + 1U); - } - } - } - - if (found == OSI_NONE) { - /* No entry found return error */ - return -1; - } - - return 0; -} - -/** - * @brief frp_req_entries - Calculates required FRP entries. - * - * Algorithm: Calculates required FRP entries for - * the given offset and data length. - * - * @param[in] offset: Actual match data offset position. - * @param[in] match_length: Match data length. - * - * @retval No of FRP entries required. - */ -static unsigned char frp_req_entries(unsigned char offset, - unsigned char match_length) -{ - unsigned char req = 0U; - - /* Validate for match_length */ - if ((match_length == OSI_NONE) || - (match_length > OSI_FRP_MATCH_DATA_MAX)) { - /* return zero */ - return req; - } - - /* Check does the given length can fit in fist entry */ - if (match_length <= (unsigned char) FRP_OFFSET_BYTES(offset)) { - /* Require one entry */ - return 1U; - } - /* Initialize req as 1U and decrement length by FRP_OFFSET_BYTES */ - req = 1U; - match_length = (unsigned char) (match_length - (unsigned char) FRP_OFFSET_BYTES(offset)); - if ((match_length / FRP_MD_SIZE) < OSI_FRP_MATCH_DATA_MAX) { - req = (unsigned char) (req + (match_length / FRP_MD_SIZE)); - if ((match_length % FRP_MD_SIZE) != OSI_NONE) { - /* Need one more entry */ - req = (unsigned char) (req + 1U); - } - } - - return req; -} - -/** - * @brief frp_entry_mode_parse - Filter mode parse function. - * - * Algorithm: Parse give filter mode and set's FRP entry flags. - * - * @param[in] filter_mode: Filter mode from FRP command. - * @param[in] data: FRP entry data pointer. - * - */ -static void frp_entry_mode_parse(unsigned char filter_mode, - struct osi_core_frp_data *data) -{ - switch (filter_mode) { - case OSI_FRP_MODE_ROUTE: - data->accept_frame = OSI_ENABLE; - data->reject_frame = OSI_DISABLE; - data->inverse_match = OSI_DISABLE; - break; - case OSI_FRP_MODE_DROP: - data->accept_frame = OSI_DISABLE; - data->reject_frame = OSI_ENABLE; - data->inverse_match = OSI_DISABLE; - break; - case OSI_FRP_MODE_BYPASS: - data->accept_frame = OSI_ENABLE; - data->reject_frame = OSI_ENABLE; - data->inverse_match = OSI_DISABLE; - break; - case OSI_FRP_MODE_LINK: - data->accept_frame = OSI_DISABLE; - data->reject_frame = OSI_DISABLE; - data->inverse_match = OSI_DISABLE; - break; - case OSI_FRP_MODE_IM_ROUTE: - data->accept_frame = OSI_ENABLE; - data->reject_frame = OSI_DISABLE; - data->inverse_match = OSI_ENABLE; - break; - case OSI_FRP_MODE_IM_DROP: - data->accept_frame = OSI_DISABLE; - data->reject_frame = OSI_ENABLE; - data->inverse_match = OSI_ENABLE; - break; - case OSI_FRP_MODE_IM_BYPASS: - data->accept_frame = OSI_ENABLE; - data->reject_frame = OSI_ENABLE; - data->inverse_match = OSI_ENABLE; - break; - case OSI_FRP_MODE_IM_LINK: - data->accept_frame = OSI_DISABLE; - data->reject_frame = OSI_DISABLE; - data->inverse_match = OSI_DISABLE; - break; - default: - //OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - // "Invalid filter mode argment\n", - // filter_mode); - break; - } -} - -/** - * @brief frp_entry_add - Add new FRP entries in table. - * - * Algorithm: This function will prepare the FRP entries - * for given inputs add or update them from a given - * position into the FRP table. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] frp_id: FRP ID to add. - * @param[in] match: Pointer to match data. - * @param[in] length: Match data length. - * @param[in] offset: Actual match data offset position. - * @param[in] filter_mode: Filter mode from FRP command. - * @param[in] next_frp_id: FRP ID to link this ID. - * @param[in] dma_sel: Indicate the DMA Channel Number (1-bit for each). - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_entry_add(struct osi_core_priv_data *const osi_core, - int frp_id, - unsigned char pos, - unsigned char *const match, - unsigned char length, - unsigned char offset, - unsigned char filter_mode, - int next_frp_id, - unsigned int dma_sel) -{ - struct osi_core_frp_entry *entry = OSI_NULL; - struct osi_core_frp_data *data = OSI_NULL; - unsigned int req_entries = 0U; - unsigned char ok_index = 0U; - unsigned char fo_t = 0U; - unsigned char fp_t = 0U; - unsigned char i = 0U, j = 0U, md_pos = 0U; - - /* Validate length */ - if (length > OSI_FRP_MATCH_DATA_MAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Invalid match length\n", - length); - return -1; - } - - /* Validate filter_mode */ - if (filter_mode >= OSI_FRP_MODE_MAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid filter mode argment\n", - filter_mode); - return -1; - } - - /* Validate offset */ - if (offset >= OSI_FRP_OFFSET_MAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid offset value\n", - offset); - return -1; - } - - /* Check for avilable space */ - req_entries = frp_req_entries(offset, length); - if ((req_entries >= OSI_FRP_MAX_ENTRY) || - (req_entries + pos) >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "No space to update FRP ID\n", - OSI_NONE); - return -1; - } - - /* Validate next_frp_id index ok_index */ - if (filter_mode == OSI_FRP_MODE_LINK || - filter_mode == OSI_FRP_MODE_IM_LINK) { - if (frp_entry_find(osi_core, next_frp_id, &i, &j) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "No Link FRP ID index found\n", - OSI_NONE); - i = (unsigned char) next_frp_id; - } - ok_index = i; - } - - /* Start data fill from 0U ... (length - 1U) */ - fo_t = (offset / FRP_MD_SIZE); - fp_t = (offset % FRP_MD_SIZE); - md_pos = 0U; - for (i = 0U; i < req_entries; i++) { - /* Get FRP entry*/ - entry = &osi_core->frp_table[pos]; - data = &entry->data; - - /* Fill FRP ID */ - entry->frp_id = frp_id; - - /* Fill MD and ME */ - data->match_data = OSI_NONE; - data->match_en = OSI_NONE; - for (j = fp_t; j < FRP_MD_SIZE; j++) { - data->match_data |= ((unsigned int)match[md_pos]) - << (j * FRP_ME_BYTE_SHIFT); - data->match_en |= ((unsigned int)FRP_ME_BYTE << - (j * FRP_ME_BYTE_SHIFT)); - md_pos++; - if (md_pos >= length) { - /* data fill completed */ - break; - } - } - - /* Fill FO */ - data->frame_offset = fo_t; - - /* Fill AF, RF, and IM flags */ - frp_entry_mode_parse(filter_mode, data); - - /* Fill DCH */ - data->dma_chsel = dma_sel; - - /* Check for the remain data and update FRP flags */ - if (md_pos < length) { - /* Reset AF, RF and set NIC, OKI */ - data->accept_frame = OSI_DISABLE; - data->reject_frame = OSI_DISABLE; - data->next_ins_ctrl = OSI_ENABLE; - - /* Init next FRP entry */ - pos++; - fo_t++; - fp_t = OSI_NONE; - data->ok_index = pos; - } else { - data->next_ins_ctrl = OSI_DISABLE; - data->ok_index = OSI_DISABLE; - } - } - - /* Check and fill final OKI */ - if (filter_mode == OSI_FRP_MODE_LINK || - filter_mode == OSI_FRP_MODE_IM_LINK) { - /* Update NIC and OKI in final entry */ - data->next_ins_ctrl = OSI_ENABLE; - data->ok_index = ok_index; - } - - return 0; -} - -/** - * @brief frp_hw_write - Update HW FRP table. - * - * Algorithm: Update FRP table into HW. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_hw_write(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p) -{ - int ret = -1, tmp = -1; - struct osi_core_frp_entry *entry; - unsigned int frp_cnt = osi_core->frp_cnt, i = OSI_NONE; - - /* Disable the FRP in HW */ - ret = ops_p->config_frp(osi_core, OSI_DISABLE); - if (ret < 0) { - /* Fail to disable try to enable it back */ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "HW Fail on FRP update\n", - OSI_NONE); - goto hw_write_enable_frp; - } - - /* Write FRP entries into HW */ - for (i = 0; i < frp_cnt; i++) { - entry = &osi_core->frp_table[i]; - ret = ops_p->update_frp_entry(osi_core, i, &entry->data); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP entry\n", - OSI_NONE); - goto hw_write_enable_frp; - } - } - - /* Update the NVE */ - ret = ops_p->update_frp_nve(osi_core, (frp_cnt - 1U)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP NVE\n", - OSI_NONE); - } - - /* Enable the FRP in HW */ -hw_write_enable_frp: - tmp = ops_p->config_frp(osi_core, OSI_ENABLE); - return (ret < 0) ? ret : tmp; -} - -/** - * @brief frp_add_proto - Process and update FRP Command Protocal Entry. - * - * Algorithm: Parse give FRP command and update Protocal Entry. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * @param[in] pos: Pointer to the FRP entry position. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_add_proto(struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd, - unsigned char *pos) -{ - int ret = -1, proto_oki = -1; - unsigned char proto_entry = OSI_DISABLE; - unsigned char req = 0U; - unsigned char proto_match[FRP_PROTO_LENGTH]; - unsigned char proto_lendth; - unsigned char proto_offset; - unsigned char match_type = cmd->match_type; - - switch (match_type) { - case OSI_FRP_MATCH_L4_S_UPORT: - proto_entry = OSI_ENABLE; - proto_match[0] = FRP_L4_UDP_MD; - proto_lendth = 1U; - proto_offset = FRP_L4_IP4_PROTO_OFFSET; - break; - case OSI_FRP_MATCH_L4_D_UPORT: - proto_entry = OSI_ENABLE; - proto_match[0] = FRP_L4_UDP_MD; - proto_lendth = 1U; - proto_offset = FRP_L4_IP4_PROTO_OFFSET; - break; - case OSI_FRP_MATCH_L4_S_TPORT: - proto_entry = OSI_ENABLE; - proto_match[0] = FRP_L4_TCP_MD; - proto_lendth = 1U; - proto_offset = FRP_L4_IP4_PROTO_OFFSET; - break; - case OSI_FRP_MATCH_L4_D_TPORT: - proto_entry = OSI_ENABLE; - proto_match[0] = FRP_L4_TCP_MD; - proto_lendth = 1U; - proto_offset = FRP_L4_IP4_PROTO_OFFSET; - break; - case OSI_FRP_MATCH_VLAN: - proto_entry = OSI_ENABLE; - proto_match[0] = FRP_L2_VLAN_MD0; - proto_match[1] = FRP_L2_VLAN_MD1; - proto_lendth = 2U; - proto_offset = FRP_L2_VLAN_PROTO_OFFSET; - break; - case OSI_FRP_MATCH_NORMAL: - default: - proto_entry = OSI_DISABLE; - break; - } - - /* Check and Add protocol FRP entire */ - if (proto_entry == OSI_ENABLE) { - /* Check for space */ - req = (unsigned char) (frp_req_entries(cmd->offset, cmd->match_length) + 1U); - if (*pos > (OSI_FRP_MAX_ENTRY - req)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail add FRP protocol entry\n", - OSI_NONE); - return -1; - } - - /* Add protocol FRP entire */ - proto_oki = *pos + 1; - ret = frp_entry_add(osi_core, cmd->frp_id, *pos, - proto_match, proto_lendth, - proto_offset, OSI_FRP_MODE_LINK, - proto_oki, cmd->dma_sel); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail add FRP protocol entry\n", - OSI_NONE); - return ret; - } - - /* Increment pos value */ - *pos = (unsigned char) (*pos + 1U); - } - - return 0; -} - -/** - * @brief frp_parse_offset - Process and update FRP Command offset. - * - * Algorithm: Parse give FRP command match type and update it's offset. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - */ -static void frp_parse_mtype(OSI_UNUSED struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd) -{ - unsigned char offset; - unsigned char match_type = cmd->match_type; - - switch (match_type) { - case OSI_FRP_MATCH_L2_DA: - offset = FRP_L2_DA_OFFSET; - break; - case OSI_FRP_MATCH_L2_SA: - offset = FRP_L2_SA_OFFSET; - break; - case OSI_FRP_MATCH_L3_SIP: - offset = FRP_L3_IP4_SIP_OFFSET; - break; - case OSI_FRP_MATCH_L3_DIP: - offset = FRP_L3_IP4_DIP_OFFSET; - break; - case OSI_FRP_MATCH_L4_S_UPORT: - offset = FRP_L4_IP4_SPORT_OFFSET; - break; - case OSI_FRP_MATCH_L4_D_UPORT: - offset = FRP_L4_IP4_DPORT_OFFSET; - break; - case OSI_FRP_MATCH_L4_S_TPORT: - offset = FRP_L4_IP4_SPORT_OFFSET; - break; - case OSI_FRP_MATCH_L4_D_TPORT: - offset = FRP_L4_IP4_DPORT_OFFSET; - break; - case OSI_FRP_MATCH_VLAN: - offset = FRP_L2_VLAN_TAG_OFFSET; - break; - case OSI_FRP_MATCH_NORMAL: - default: - offset = cmd->offset; - break; - } - - /* Update command offset */ - cmd->offset = offset; -} - -/** - * @brief frp_delete - Process FRP Delete Command. - * - * Algorithm: Parse give FRP delete command and update it on OSI data and HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_delete(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) -{ - int ret = -1; - unsigned char i = 0U, pos = 0U, count = 0U; - int frp_id = cmd->frp_id; - unsigned int frp_cnt = osi_core->frp_cnt; - - /* Check for FRP entries */ - if (frp_cnt == 0U) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "No FRP entries in the table\n", - OSI_NONE); - return -1; - } - - /* Find the FRP entry */ - if (frp_entry_find(osi_core, frp_id, &pos, &count) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "No FRP entry found to delete\n", - OSI_NONE); - return -1; - } - - /* Validate pos and count */ - if (((unsigned int)pos + count) > frp_cnt) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalid FRP entry index\n", - OSI_NONE); - return -1; - } - - /* Update the frp_table entry */ - osi_memset(&osi_core->frp_table[pos], 0U, - (sizeof(struct osi_core_frp_entry) * count)); - - /* Move in FRP table entries by count */ - for (i = (unsigned char) (pos + count); i <= frp_cnt; i++) { - frp_entry_copy(&osi_core->frp_table[pos], - &osi_core->frp_table[i]); - pos++; - } - - /* Write FRP Table into HW */ - ret = frp_hw_write(osi_core, ops_p); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP NVE\n", - OSI_NONE); - } - - /* Update the frp_cnt entry */ - osi_core->frp_cnt = (frp_cnt - count); - - return ret; -} - -/** - * @brief frp_update - Process FRP Update Command. - * - * Algorithm: Parse give FRP update command and update it on OSI data and HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_update(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) -{ - int ret = -1; - unsigned char pos = 0U, count = 0U, req = 0U; - int frp_id = cmd->frp_id; - - /* Validate given frp_id */ - if (frp_entry_find(osi_core, frp_id, &pos, &count) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "No FRP entry found\n", - OSI_NONE); - return -1; - } - - /* Parse match type and update command offset */ - frp_parse_mtype(osi_core, cmd); - - /* Calculate the required FRP entries for Update Command. */ - req = frp_req_entries(cmd->offset, cmd->match_length); - switch (cmd->match_type) { - case OSI_FRP_MATCH_L4_S_UPORT: - case OSI_FRP_MATCH_L4_D_UPORT: - case OSI_FRP_MATCH_L4_S_TPORT: - case OSI_FRP_MATCH_L4_D_TPORT: - case OSI_FRP_MATCH_VLAN: - req++; - break; - default: - /* No need of Protocal Entry */ - break; - } - - /* Reject update on old and new required FRP entries mismatch */ - if (count != req) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Old and New required FRP entries mismatch\n", - OSI_NONE); - return -1; - } - - /* Process and update FRP Command Protocal Entry */ - ret = frp_add_proto(osi_core, cmd, &pos); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to parse match type\n", - OSI_NONE); - return ret; - } - - /* Update FRP entries */ - ret = frp_entry_add(osi_core, frp_id, pos, - cmd->match, cmd->match_length, - cmd->offset, cmd->filter_mode, - cmd->next_frp_id, cmd->dma_sel); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP entry\n", - OSI_NONE); - return ret; - } - - /* Write FRP Table into HW */ - ret = frp_hw_write(osi_core, ops_p); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP NVE\n", - OSI_NONE); - } - - return ret; -} - -/** - * @brief frp_add - Process FRP Add Command. - * - * Algorithm: Parse give FRP Add command and update it on OSI data and HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -static int frp_add(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) -{ - int ret = -1; - unsigned char pos = 0U, count = 0U; - int frp_id = cmd->frp_id; - unsigned int nve = osi_core->frp_cnt; - - /* Check for MAX FRP entries */ - if (nve >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "FRP etries are full\n", - nve); - return -1; - } - - /* Check the FRP entry already exists */ - ret = frp_entry_find(osi_core, frp_id, &pos, &count); - if (ret >= 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "FRP entry already exists\n", - OSI_NONE); - return -1; - } - - /* Parse match type and update command offset */ - frp_parse_mtype(osi_core, cmd); - - /* Process and add FRP Command Protocal Entry */ - ret = frp_add_proto(osi_core, cmd, (unsigned char *)&nve); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to parse match type\n", - OSI_NONE); - return ret; - } - - /* Add Match data FRP Entry */ - ret = frp_entry_add(osi_core, frp_id, (unsigned char)nve, - cmd->match, cmd->match_length, - cmd->offset, cmd->filter_mode, - cmd->next_frp_id, cmd->dma_sel); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to add FRP entry\n", - nve); - return ret; - } - osi_core->frp_cnt = nve + frp_req_entries(cmd->offset, - cmd->match_length); - - /* Write FRP Table into HW */ - ret = frp_hw_write(osi_core, ops_p); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to update FRP NVE\n", - OSI_NONE); - } - - return ret; -} - -/** - * @brief setup_frp - Process OSD FRP Command. - * - * Algorithm: Parse give FRP command and update it on OSI data and HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -int setup_frp(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd) -{ - int ret = -1; - - switch (cmd->cmd) { - case OSI_FRP_CMD_ADD: - ret = frp_add(osi_core, ops_p, cmd); - break; - case OSI_FRP_CMD_UPDATE: - ret = frp_update(osi_core, ops_p, cmd); - break; - case OSI_FRP_CMD_DEL: - ret = frp_delete(osi_core, ops_p, cmd); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalid FRP command\n", - cmd->cmd); - break; - } - - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "FRP instrctions count\n", - osi_core->frp_cnt); - - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "FRP command fail\n", - cmd->cmd); - } - - return ret; -} - -/** - * @brief init_frp - Initialize FRP. - * - * Algorithm: Reset all the data in the FRP table Initialize FRP count to zero. - * - * @param[in] osi_core: OSI core private data structure. - * - */ -void init_frp(struct osi_core_priv_data *const osi_core) -{ - /* Reset the NVE count to zero */ - osi_core->frp_cnt = 0U; - /* Clear all instruction of FRP */ - osi_memset(osi_core->frp_table, 0U, - (sizeof(struct osi_core_frp_entry) * OSI_FRP_MAX_ENTRY)); -} diff --git a/osi/core/frp.h b/osi/core/frp.h deleted file mode 100644 index d1092b7..0000000 --- a/osi/core/frp.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2020, 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 FRP_H -#define FRP_H - -#include -#include -#include "core_local.h" - -#define FRP_MD_SIZE (4U) -#define FRP_ME_BYTE (0xFFU) -#define FRP_ME_BYTE_SHIFT (8U) - -/* Offset defines for Match data types */ -#define FRP_L2_DA_OFFSET 0U -#define FRP_L2_SA_OFFSET 6U -#define FRP_L2_VLAN_TAG_OFFSET 14U -#define FRP_L3_IP4_SIP_OFFSET 26U -#define FRP_L3_IP4_DIP_OFFSET 30U -#define FRP_L4_IP4_SPORT_OFFSET 34U -#define FRP_L4_IP4_DPORT_OFFSET 36U - -/* Protocols Match data define values  */ -#define FRP_PROTO_LENGTH 2U -#define FRP_L2_VLAN_PROTO_OFFSET 12U -#define FRP_L2_VLAN_MD0 0x81U -#define FRP_L2_VLAN_MD1 0x00U -#define FRP_L4_IP4_PROTO_OFFSET 23U -#define FRP_L4_UDP_MD 17U -#define FRP_L4_TCP_MD 6U - -/* Define for FRP Entries offsets and lengths */ -#define FRP_OFFSET_BYTES(offset) \ - (FRP_MD_SIZE - ((offset) % FRP_MD_SIZE)) - -/** - * @brief setup_frp - Process OSD FRP Command. - * - * Algorithm: Parse give FRP command and update it on OSI data and HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: OSI FRP command structure. - * - * @retval 0 on success. - * @retval -1 on failure. - */ -int setup_frp(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_core_frp_cmd *const cmd); - -/** - * @brief init_frp - Init the FRP Instruction Table. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC and PHY should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -void init_frp(struct osi_core_priv_data *const osi_core); - -#endif /* FRP_H */ diff --git a/osi/core/ivc_core.c b/osi/core/ivc_core.c deleted file mode 100644 index fe40e26..0000000 --- a/osi/core/ivc_core.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 -#include "eqos_core.h" -#include "eqos_mmc.h" -#include "core_local.h" -#include "../osi/common/common.h" -#include "macsec.h" - -/** - * @brief ivc_safety_config - EQOS MAC core safety configuration - */ -static struct core_func_safety ivc_safety_config; - -/** - * @brief ivc_handle_ioctl - marshell input argument to handle runtime command - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] data: OSI IOCTL data structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval data from PHY register on success - * @retval -1 on failure - */ -static nve32_t ivc_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data) -{ - nve32_t ret = 0; - ivc_msg_common_t msg; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = handle_ioctl; - msg.status = osi_memcpy((void *)&msg.data.ioctl_data, - (void *)data, - sizeof(struct osi_ioctl)); - - if (data->cmd == OSI_CMD_CONFIG_PTP) { - osi_memcpy((void *)&msg.data.ioctl_data.ptp_config, - (void *)&osi_core->ptp_config, - sizeof(struct osi_ptp_config)); - } - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - - if (data->cmd == OSI_CMD_READ_MMC) { - msg.status = osi_memcpy((void *)&osi_core->mmc, - (void *)&msg.data.mmc, - sizeof(struct osi_mmc_counters)); - } else { - msg.status = osi_memcpy((void *)data, - (void *)&msg.data.ioctl_data, - sizeof(struct osi_ioctl)); - } - return ret; -} - -/** - * @brief ivc_core_init - EQOS MAC, MTL and common DMA Initialization - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_fifo_size: MTL TX FIFO size - * @param[in] rx_fifo_size: MTL RX FIFO size - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_core_init(struct osi_core_priv_data *const osi_core, - OSI_UNUSED nveu32_t tx_fifo_size, - OSI_UNUSED nveu32_t rx_fifo_size) -{ - ivc_msg_common_t msg; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = core_init; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - - -/** - * @brief ivc_core_deinit - EQOS MAC core deinitialization - * - * @param[in] osi_core: OSI core private data structure. - * - * @note Required clks and resets has to be enabled - */ -static void ivc_core_deinit(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = handle_ioctl; - msg.data.ioctl_data.cmd = OSI_CMD_STOP_MAC; - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret < 0) { - /* handle Error */ - } - -} - -/** - * @brief ivc_write_phy_reg - Write to a PHY register through MAC over MDIO bus - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be write to PHY. - * @param[in] phydata: Data to write to a PHY register. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t ivc_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg, - const nveu16_t phydata) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = write_phy_reg; - msg.data.args.arguments[index++] = phyaddr; - msg.data.args.arguments[index++] = phyreg; - msg.data.args.arguments[index++] = phydata; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - - -/** - * @brief ivc_read_phy_reg - Read from a PHY register through MAC over MDIO bus - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be read from PHY. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval data from PHY register on success - * @retval -1 on failure - */ -static nve32_t ivc_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, - const nveu32_t phyreg) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = read_phy_reg; - msg.data.args.arguments[index++] = phyaddr; - msg.data.args.arguments[index++] = phyreg; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -#ifdef MACSEC_SUPPORT -/** - * @brief ivc_macsec_dbg_events_config - Configure Debug events - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: Config Buffer - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int ivc_macsec_dbg_events_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = dbg_events_config_macsec; - - msg.status = osi_memcpy((void *)&msg.data.dbg_buf_config, - (void *)dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - msg.status = osi_memcpy((void *)dbg_buf_config, - (void *)&msg.data.dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); - - return ret; -} - -/** - * @brief macsec_dbg_buf_config - Read/Write debug buffers. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] dbg_buf_config: Pointer to debug buffer config data structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_dbg_buf_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = dbg_buf_config_macsec; - - msg.status = osi_memcpy((void *)&msg.data.dbg_buf_config, - (void *)dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - msg.status = osi_memcpy((void *)dbg_buf_config, - (void *) &msg.data.dbg_buf_config, - sizeof(struct osi_macsec_dbg_buf_config)); - - return ret; -} - -/** - * @brief macsec_read_mmc - To read statitics registers and update structure - * variable - * - * Algorithm: Pass register offset and old value to helper function and - * update structure. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC/MACSEC should be init and started. - */ -static void ivc_macsec_read_mmc(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = read_mmc_macsec; - - msg.status = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - - msg.status = osi_memcpy((void *)&osi_core->macsec_mmc, - (void *) &msg.data.macsec_mmc, - sizeof(struct osi_macsec_mmc_counters)); - msg.status = osi_memcpy((void *)&osi_core->macsec_irq_stats, - (void *) &msg.data.macsec_irq_stats, - sizeof(struct osi_macsec_irq_stats)); -} - -/** - * @brief ivc_get_sc_lut_key_index - Macsec get Key_index - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] sc: Secure Channel info. - * @param[in] enable: enable or disable. - * @param[in] ctlr: Controller instance. - * @param[[out] kt_idx: Key table index to program SAK. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nveu32_t *key_index, - nveu16_t ctlr) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = macsec_get_sc_lut_key_index; - msg.status = osi_memcpy((void *) &msg.data.macsec_cfg.sci, - (void *)sci, - OSI_SCI_LEN); - msg.data.macsec_cfg.ctlr = ctlr; - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - *key_index = msg.data.macsec_cfg.key_index; - return ret; -} - -/** - * @brief ivc_macsec_config - Mac sec config. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] sc: Secure Channel info. - * @param[in] enable: enable or disable. - * @param[in] ctlr: Controller instance. - * @param[[out] kt_idx: Key table index to program SAK. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - unsigned int enable, unsigned short ctlr, - unsigned short *kt_idx) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = config_macsec; - msg.status = osi_memcpy((void *) &msg.data.macsec_cfg.sc_info, - (void *)sc, - sizeof(struct osi_macsec_sc_info)); - msg.data.macsec_cfg.enable = enable; - msg.data.macsec_cfg.ctlr = ctlr; - msg.data.macsec_cfg.kt_idx = *kt_idx; - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - *kt_idx = msg.data.macsec_cfg.kt_idx; - return ret; -} - -/** - * @brief ivc_macsec_update_mtu - Update MACSEC mtu. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] mtu: MACSEC MTU len. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t ivc_macsec_update_mtu(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = macsec_update_mtu_size; - msg.data.args.arguments[index] = mtu; - index++; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -/** - * @brief ivc_macsec_enable - Enable or disable Macsec. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] enable: Enable or Disable Macsec. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_enable(struct osi_core_priv_data *const osi_core, - unsigned int enable) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = en_macsec; - msg.data.args.arguments[index] = enable; - index++; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -/** - * @brief ivc_macsec_loopback_config - Loopback configure. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] enable: Enable or disable loopback. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_loopback_config(struct osi_core_priv_data *const osi_core, - unsigned int enable) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = loopback_config_macsec; - msg.data.args.arguments[index] = enable; - index++; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -#ifdef MACSEC_KEY_PROGRAM -/** - * @brief ivc_macsec_kt_config - MacSec KT configure. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] kt_config: KT config structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t ivc_macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = kt_config_macsec; - msg.status = osi_memcpy((void *) &msg.data.kt_config, - (void *)kt_config, - sizeof(struct osi_macsec_kt_config)); - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - msg.status = osi_memcpy((void *)kt_config, - (void *)&msg.data.kt_config, - sizeof(struct osi_macsec_kt_config)); - return ret; -} -#endif /* MACSEC_KEY_PROGRAM */ - -/** - * @brief ivc_macsec_cipher_config - cipher configure. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] cipher: value of cipher. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_cipher_config(struct osi_core_priv_data *const osi_core, - unsigned int cipher) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = cipher_config; - msg.data.args.arguments[index] = cipher; - index++; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} -/** - * @brief ivc_macsec_lut_config - LUT config. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] lut_config: lut data structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t ivc_macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - ivc_msg_common_t msg; - nve32_t ret = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = lut_config_macsec; - msg.status = osi_memcpy((void *) &msg.data.lut_config, - (void *)lut_config, - sizeof(struct osi_macsec_lut_config)); - - ret = osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); - if (ret != 0) { - return ret; - } - - msg.status = osi_memcpy((void *)lut_config, - (void *)&msg.data.lut_config, - sizeof(struct osi_macsec_lut_config)); - return ret; -} - -/** - * @brief ivc_macsec_handle_s_irq - handle s irq. - * - * @param[in] osi_core: OSI Core private data structure. - * - */ -static void ivc_macsec_handle_s_irq(OSI_UNUSED - struct osi_core_priv_data *const osi_core) -{ - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Nothing to handle \n", 0ULL); -} - -/** - * @brief ivc_macsec_handle_ns_irq - handle ns irq. - * - * @param[in] osi_core: OSI Core private data structure. - * - */ - -static void ivc_macsec_handle_ns_irq(OSI_UNUSED - struct osi_core_priv_data *const osi_core) -{ - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Nothing to handle \n", 0ULL); -} - -/** - * @brief ivc_macsec_deinit - De Initialize. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ - -static int ivc_macsec_deinit(struct osi_core_priv_data *const osi_core) -{ - ivc_msg_common_t msg; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = deinit_macsec; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -/** - * @brief ivc_macsec_init -Initialize. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] genl_info: Generic netlink information structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static int ivc_macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - ivc_msg_common_t msg; - nveu32_t index = 0; - - osi_memset(&msg, 0, sizeof(msg)); - - msg.cmd = init_macsec; - msg.data.args.arguments[index] = mtu; - index++; - msg.data.args.count = index; - - return osi_core->osd_ops.ivc_send(osi_core, &msg, sizeof(msg)); -} - -/** - * @brief ivc_init_macsec_ops - Initialize IVC core operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void ivc_init_macsec_ops(void *macsecops) -{ - struct osi_macsec_core_ops *ops = (struct osi_macsec_core_ops *) macsecops; - - ops->init = ivc_macsec_init; - ops->deinit = ivc_macsec_deinit; - ops->handle_ns_irq = ivc_macsec_handle_ns_irq; - ops->handle_s_irq = ivc_macsec_handle_s_irq; - ops->lut_config = ivc_macsec_lut_config; -#ifdef MACSEC_KEY_PROGRAM - ops->kt_config = ivc_macsec_kt_config; -#endif /* MACSEC_KEY_PROGRAM */ - ops->cipher_config = ivc_macsec_cipher_config; - ops->loopback_config = ivc_macsec_loopback_config; - ops->macsec_en = ivc_macsec_enable; - ops->config = ivc_macsec_config; - ops->read_mmc = ivc_macsec_read_mmc; - ops->dbg_buf_config = ivc_macsec_dbg_buf_config; - ops->dbg_events_config = ivc_macsec_dbg_events_config; - ops->get_sc_lut_key_index = ivc_get_sc_lut_key_index; - ops->update_mtu = ivc_macsec_update_mtu; -} -#endif - -/** - * @brief ivc_get_core_safety_config - EQOS MAC safety configuration - */ -void *ivc_get_core_safety_config(void) -{ - return &ivc_safety_config; -} - -/** - * @brief vir_ivc_core_deinit - MAC core deinitialization - * - * @param[in] osi_core: OSI core private data structure. - * - * @note Required clks and resets has to be enabled - * - * @retval Return 0 - */ -static nve32_t vir_ivc_core_deinit(struct osi_core_priv_data *const osi_core) -{ - ivc_core_deinit(osi_core); - return 0; -} - -/** - * @brief vir_init_core_ops - core ops initialization - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval Return 0 - */ -static nve32_t vir_ivc_init_core_ops(OSI_UNUSED - struct osi_core_priv_data *const osi_core) -{ - /* This API should not do anything as ethernet_server maintain ops - * locally - */ - return 0; -} - -void ivc_interface_init_core_ops(struct if_core_ops *if_ops_p) -{ - if_ops_p->if_core_init = ivc_core_init; - if_ops_p->if_core_deinit = vir_ivc_core_deinit; - if_ops_p->if_write_phy_reg = ivc_write_phy_reg; - if_ops_p->if_read_phy_reg = ivc_read_phy_reg; - if_ops_p->if_init_core_ops = vir_ivc_init_core_ops; - if_ops_p->if_handle_ioctl = ivc_handle_ioctl; -} diff --git a/osi/core/libnvethernetrm.export b/osi/core/libnvethernetrm.export deleted file mode 100644 index d27755a..0000000 --- a/osi/core/libnvethernetrm.export +++ /dev/null @@ -1,49 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 2019-2022, 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. -# -# libnvethernetrm interface export -# -############################################################################### -osi_init_core_ops -osi_write_phy_reg -osi_read_phy_reg -osi_hw_core_init -osi_hw_core_deinit -osi_get_core -osi_handle_ioctl -#Below need to be enabled when MACSEC is enabled -#osi_macsec_en -#osi_macsec_deinit -#osi_macsec_ns_isr -#osi_macsec_s_isr -#osi_macsec_init -#osi_macsec_cipher_config -#osi_macsec_config -#osi_init_macsec_ops -#osi_macsec_config_lut -#osi_macsec_loopback -#osi_macsec_read_mmc -#osi_macsec_config_dbg_buf -#osi_macsec_dbg_events_config -#osi_macsec_config_kt -#osi_macsec_get_sc_lut_key_index -#osi_macsec_update_mtu diff --git a/osi/core/macsec.c b/osi/core/macsec.c deleted file mode 100644 index a1c545f..0000000 --- a/osi/core/macsec.c +++ /dev/null @@ -1,5883 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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. - */ - -#ifdef MACSEC_SUPPORT -#include -#include "macsec.h" -#include "../osi/common/common.h" -#include "core_local.h" - -#if defined(DEBUG_MACSEC) && defined(QNX_OS) -#define LOG(...) \ - { \ - slogf(0, 2, ##__VA_ARGS__); \ - } - -#elif defined(DEBUG_MACSEC) && defined(LINUX_OS) -#include -#define LOG(...) \ - { \ - pr_err(##__VA_ARGS__); \ - } -#else -#define LOG(...) -#endif - -/** - * @brief poll_for_dbg_buf_update - Query the status of a debug buffer update. - * - * @note - * Algorithm: - * - Waits for reset of MACSEC_DEBUG_BUF_CONFIG_0_UPDATE for max polling count of 1000. - * - Sleeps for 1 micro sec for each iteration. - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base, osd_ops.udelay. - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t poll_for_dbg_buf_update(struct osi_core_priv_data *const osi_core) -{ - nveu32_t retry = RETRY_COUNT; - nveu32_t dbg_buf_config; - nve32_t cond = COND_NOT_MET; - nveu32_t count; - - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "timeout!\n", 0ULL); - return -1; - } - - dbg_buf_config = osi_readla(osi_core, - (nveu8_t *)osi_core->macsec_base + - MACSEC_DEBUG_BUF_CONFIG_0); - if ((dbg_buf_config & MACSEC_DEBUG_BUF_CONFIG_0_UPDATE) == OSI_NONE) { - cond = COND_MET; - } - - count++; - /* wait on UPDATE bit to reset */ - osi_core->osd_ops.udelay(RETRY_DELAY); - } - - return 0; - -} - -/** - * @brief write_dbg_buf_data - Commit debug buffer to HW - * - * @note - * Algorithm: - * - Writes debug buffer data to MACSEC_DEBUG_BUF_DATA_0 register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf: Pointer to debug buffer data to be written - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void write_dbg_buf_data( - struct osi_core_priv_data *const osi_core, - nveu32_t const *const dbg_buf) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t i; - - /* Commit the dbg buffer to HW */ - for (i = 0; i < DBG_BUF_LEN; i++) { - osi_writela(osi_core, dbg_buf[i], base + - MACSEC_DEBUG_BUF_DATA_0(i)); - } -} - -/** - * @brief read_dbg_buf_data - Read debug buffer from HW - * - * @note - * Algorithm: - * - Reads debug buffer data from MACSEC_DEBUG_BUF_DATA_0 register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf: Pointer to debug buffer data to be read - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void read_dbg_buf_data( - struct osi_core_priv_data *const osi_core, - nveu32_t *dbg_buf) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t i; - - /* Read debug buffer from HW */ - for (i = 0; i < DBG_BUF_LEN; i++) { - dbg_buf[i] = osi_readla(osi_core, base + - MACSEC_DEBUG_BUF_DATA_0(i)); - } -} - -/** - * @brief write_tx_dbg_trigger_evts - Trigger and start capturing the tx dbg events - * - * @note - * Algorithm: - * - Enables Tx Debug events for the events passed from dbg_buf_config - * - Start capturing the triggered events by enabling the same in MACSEC_TX_DEBUG_CONTROL_0 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param flags - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void write_tx_dbg_trigger_evts( - struct osi_core_priv_data *const osi_core, - const struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t flags = 0; - nveu32_t tx_trigger_evts, debug_ctrl_reg; - - flags = dbg_buf_config->flags; - tx_trigger_evts = osi_readla(osi_core, - base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - if ((flags & OSI_TX_DBG_LKUP_MISS_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_LKUP_MISS; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_LKUP_MISS; - } - - if ((flags & OSI_TX_DBG_AN_NOT_VALID_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_AN_NOT_VALID; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_AN_NOT_VALID; - } - - if ((flags & OSI_TX_DBG_KEY_NOT_VALID_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_KEY_NOT_VALID; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_KEY_NOT_VALID; - } - - if ((flags & OSI_TX_DBG_CRC_CORRUPT_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_CRC_CORRUPT; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_CRC_CORRUPT; - } - - if ((flags & OSI_TX_DBG_ICV_CORRUPT_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_ICV_CORRUPT; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_ICV_CORRUPT; - } - - if ((flags & OSI_TX_DBG_CAPTURE_EVT) != OSI_NONE) { - tx_trigger_evts |= MACSEC_TX_DBG_CAPTURE; - } else { - tx_trigger_evts &= ~MACSEC_TX_DBG_CAPTURE; - } - - LOG("%s: 0x%x", __func__, tx_trigger_evts); - osi_writela(osi_core, tx_trigger_evts, - base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - if (tx_trigger_evts != OSI_NONE) { - /** Start the tx debug buffer capture */ - debug_ctrl_reg = osi_readla(osi_core, - base + MACSEC_TX_DEBUG_CONTROL_0); - debug_ctrl_reg |= MACSEC_TX_DEBUG_CONTROL_0_START_CAP; - LOG("%s: debug_ctrl_reg 0x%x", __func__, - debug_ctrl_reg); - osi_writela(osi_core, debug_ctrl_reg, - base + MACSEC_TX_DEBUG_CONTROL_0); - } -} - -/** - * @brief tx_dbg_trigger_evts - Trigger or read the Tx dbg buffer events - * - * @note - * Algorithm: - * - Enables Tx Debug events for the events passed from dbg_buf_config or - * - Reads the enabled tx dbg buffers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param rw, flags - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void tx_dbg_trigger_evts( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t flags = 0; - nveu32_t tx_trigger_evts; - - if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { - write_tx_dbg_trigger_evts(osi_core, dbg_buf_config); - } else { - tx_trigger_evts = osi_readla(osi_core, - base + MACSEC_TX_DEBUG_TRIGGER_EN_0); - LOG("%s: 0x%x", __func__, tx_trigger_evts); - if ((tx_trigger_evts & MACSEC_TX_DBG_LKUP_MISS) != OSI_NONE) { - flags |= OSI_TX_DBG_LKUP_MISS_EVT; - } - if ((tx_trigger_evts & MACSEC_TX_DBG_AN_NOT_VALID) != OSI_NONE) { - flags |= OSI_TX_DBG_AN_NOT_VALID_EVT; - } - if ((tx_trigger_evts & MACSEC_TX_DBG_KEY_NOT_VALID) != OSI_NONE) { - flags |= OSI_TX_DBG_KEY_NOT_VALID_EVT; - } - if ((tx_trigger_evts & MACSEC_TX_DBG_CRC_CORRUPT) != OSI_NONE) { - flags |= OSI_TX_DBG_CRC_CORRUPT_EVT; - } - if ((tx_trigger_evts & MACSEC_TX_DBG_ICV_CORRUPT) != OSI_NONE) { - flags |= OSI_TX_DBG_ICV_CORRUPT_EVT; - } - if ((tx_trigger_evts & MACSEC_TX_DBG_CAPTURE) != OSI_NONE) { - flags |= OSI_TX_DBG_CAPTURE_EVT; - } - dbg_buf_config->flags = flags; - } -} - -/** - * @brief write_rx_dbg_trigger_evts - Trigger and start capturing the rx dbg events - * - * @note - * Algorithm: - * - Enables Rx Debug events for the events passed from dbg_buf_config - * - Start capturing the triggered events by enabling the same in MACSEC_RX_DEBUG_CONTROL_0 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param flags - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void write_rx_dbg_trigger_evts( - struct osi_core_priv_data *const osi_core, - const struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t flags = 0; - nveu32_t rx_trigger_evts = 0, debug_ctrl_reg; - - flags = dbg_buf_config->flags; - rx_trigger_evts = osi_readla(osi_core, - base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - if ((flags & OSI_RX_DBG_LKUP_MISS_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_LKUP_MISS; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_LKUP_MISS; - } - - if ((flags & OSI_RX_DBG_KEY_NOT_VALID_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_KEY_NOT_VALID; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_KEY_NOT_VALID; - } - - if ((flags & OSI_RX_DBG_REPLAY_ERR_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_REPLAY_ERR; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_REPLAY_ERR; - } - - if ((flags & OSI_RX_DBG_CRC_CORRUPT_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_CRC_CORRUPT; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_CRC_CORRUPT; - } - - if ((flags & OSI_RX_DBG_ICV_ERROR_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_ICV_ERROR; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_ICV_ERROR; - } - - if ((flags & OSI_RX_DBG_CAPTURE_EVT) != OSI_NONE) { - rx_trigger_evts |= MACSEC_RX_DBG_CAPTURE; - } else { - rx_trigger_evts &= ~MACSEC_RX_DBG_CAPTURE; - } - LOG("%s: 0x%x", __func__, rx_trigger_evts); - osi_writela(osi_core, rx_trigger_evts, - base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - if (rx_trigger_evts != OSI_NONE) { - /** Start the tx debug buffer capture */ - debug_ctrl_reg = osi_readla(osi_core, - base + MACSEC_RX_DEBUG_CONTROL_0); - debug_ctrl_reg |= MACSEC_RX_DEBUG_CONTROL_0_START_CAP; - LOG("%s: debug_ctrl_reg 0x%x", __func__, - debug_ctrl_reg); - osi_writela(osi_core, debug_ctrl_reg, - base + MACSEC_RX_DEBUG_CONTROL_0); - } -} - -/** - * @brief rx_dbg_trigger_evts - Trigger or read the Rx dbg buffer events - * - * @note - * Algorithm: - * - Enables Rx Debug events for the events passed from dbg_buf_config or - * - Reads the enabled rx dbg buffers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure.Used param macsec_base - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param rw, flags - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void rx_dbg_trigger_evts( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t flags = 0; - nveu32_t rx_trigger_evts = 0; - - if (dbg_buf_config->rw == OSI_DBG_TBL_WRITE) { - write_rx_dbg_trigger_evts(osi_core, dbg_buf_config); - } else { - rx_trigger_evts = osi_readla(osi_core, - base + MACSEC_RX_DEBUG_TRIGGER_EN_0); - LOG("%s: 0x%x", __func__, rx_trigger_evts); - if ((rx_trigger_evts & MACSEC_RX_DBG_LKUP_MISS) != OSI_NONE) { - flags |= OSI_RX_DBG_LKUP_MISS_EVT; - } - if ((rx_trigger_evts & MACSEC_RX_DBG_KEY_NOT_VALID) != OSI_NONE) { - flags |= OSI_RX_DBG_KEY_NOT_VALID_EVT; - } - if ((rx_trigger_evts & MACSEC_RX_DBG_REPLAY_ERR) != OSI_NONE) { - flags |= OSI_RX_DBG_REPLAY_ERR_EVT; - } - if ((rx_trigger_evts & MACSEC_RX_DBG_CRC_CORRUPT) != OSI_NONE) { - flags |= OSI_RX_DBG_CRC_CORRUPT_EVT; - } - if ((rx_trigger_evts & MACSEC_RX_DBG_ICV_ERROR) != OSI_NONE) { - flags |= OSI_RX_DBG_ICV_ERROR_EVT; - } - if ((rx_trigger_evts & MACSEC_RX_DBG_CAPTURE) != OSI_NONE) { - flags |= OSI_RX_DBG_CAPTURE_EVT; - } - dbg_buf_config->flags = flags; - } -} - -/** - * @brief validate_inputs_macsec_dbg_buf_conf - validates the dbg buffer configuration - * - * @note - * Algorithm: - * - Validates if rw and ctrl_sel is valid else returns -1 - * - Validates if the index is valid else return -1 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param rw, index, ctlr_sel - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t validate_inputs_macsec_dbg_buf_conf( - const struct osi_core_priv_data *const osi_core, - const struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - /* Validate inputs */ - if ((dbg_buf_config->rw > OSI_RW_MAX) || - (dbg_buf_config->ctlr_sel > OSI_CTLR_SEL_MAX)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Params validation failed\n", 0ULL); - return -1; - } - - if (((dbg_buf_config->ctlr_sel == OSI_CTLR_SEL_TX) && - (dbg_buf_config->index > OSI_TX_DBG_BUF_IDX_MAX)) || - ((dbg_buf_config->ctlr_sel == OSI_CTLR_SEL_RX) && - (dbg_buf_config->index > OSI_RX_DBG_BUF_IDX_MAX))) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Wrong index \n", dbg_buf_config->index); - return -1; - } - return 0; -} - -/** - * @brief validate_inputs_macsec_dbg_buf_conf - validates the dbg buffer configuration - * - * @note - * Algorithm: - * - Validates if dbg buffer configuration is valid else returns -1 - * - Reads MACSEC_DEBUG_BUF_CONFIG_0 register - * - Reads or writes the dbg buffer configuration depending on the rw field in dbg_buf_config - * - poll for read or write happens successfully - * - Read the dbg buffer if only read is enabled - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param rw, index, ctlr_sel - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_dbg_buf_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t dbg_config_reg = 0; - nve32_t ret = 0; - - if (validate_inputs_macsec_dbg_buf_conf(osi_core, dbg_buf_config) < 0) { - return -1; - } - - dbg_config_reg = osi_readla(osi_core, base + MACSEC_DEBUG_BUF_CONFIG_0); - - if (dbg_buf_config->ctlr_sel != OSI_NONE) { - dbg_config_reg |= MACSEC_DEBUG_BUF_CONFIG_0_CTLR_SEL; - } else { - dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_CTLR_SEL; - } - - if (dbg_buf_config->rw != OSI_NONE) { - dbg_config_reg |= MACSEC_DEBUG_BUF_CONFIG_0_RW; - /** Write data to debug buffer */ - write_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); - } else { - dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_RW; - } - - dbg_config_reg &= ~MACSEC_DEBUG_BUF_CONFIG_0_IDX_MASK; - dbg_config_reg |= dbg_buf_config->index ; - dbg_config_reg |= MACSEC_DEBUG_BUF_CONFIG_0_UPDATE; - osi_writela(osi_core, dbg_config_reg, base + MACSEC_DEBUG_BUF_CONFIG_0); - ret = poll_for_dbg_buf_update(osi_core); - if (ret < 0) { - return ret; - } - - if (dbg_buf_config->rw == OSI_NONE) { - read_dbg_buf_data(osi_core, dbg_buf_config->dbg_buf); - } - return 0; -} - -/** - * @brief macsec_dbg_events_config - Configures dbg events - * - * @note - * Algorithm: - * - Validates if dbg buffer configuration is valid else returns -1 - * - If more than 1 event is requested to be configured return -1 - * - Configures Tx or Rx dbg trigger events - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dbg_buf_config: Pointer to dbg buffer events. Used param rw, flags, ctlr_sel - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_dbg_events_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - nveu64_t events = 0; - nveu32_t i, flags = dbg_buf_config->flags; - - /* Validate inputs */ - if ((dbg_buf_config->rw > OSI_RW_MAX) || - (dbg_buf_config->ctlr_sel > OSI_CTLR_SEL_MAX)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Params validation failed!\n", 0ULL); - return -1; - } - - /* Only one event allowed to configure at a time */ - if ((flags != OSI_NONE) && (dbg_buf_config->rw == OSI_DBG_TBL_WRITE)) { - for (i = 0; i < 32U; i++) { - if ((flags & ((nveu32_t)(1U) << i)) != OSI_NONE) { - CERT_C__POST_INC__U64(events); - } - } - if (events > 1U) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Don't allow more than one debug events set\n", flags); - return -1; - } - } - - switch (dbg_buf_config->ctlr_sel) { - case OSI_CTLR_SEL_TX: - tx_dbg_trigger_evts(osi_core, dbg_buf_config); - break; - case OSI_CTLR_SEL_RX: - rx_dbg_trigger_evts(osi_core, dbg_buf_config); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller select\n", 0ULL); - break; - } - - return 0; -} - -/** - * @brief update_macsec_mmc_val - Reads specific macsec mmc counters - * - * @note - * Algorithm: - * - Reads and returns macsec mmc counters - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * @param[in] offset: Memory offset where mmc counters are stored - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval value of mmc counters read - */ -static inline nveul64_t update_macsec_mmc_val( - struct osi_core_priv_data *osi_core, - nveu64_t offset) -{ - nveul64_t value_lo, value_hi; - - value_lo = osi_readla(osi_core, - (nveu8_t *)osi_core->macsec_base + offset); - value_hi = osi_readla(osi_core, - (nveu8_t *)osi_core->macsec_base + - ((offset & 0xFFFFU) + 4U)); - return ((value_lo) | (value_hi << 31)); -} - -/** - * @brief macsec_read_mmc - Reads all macsec mmc counters - * - * @note - * Algorithm: - * - Reads and updates the macsec_mmc counters in osi_core - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_mmc - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void macsec_read_mmc(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_mmc_counters *mmc = &osi_core->macsec_mmc; - nveu16_t i; - - mmc->tx_pkts_untaged = - update_macsec_mmc_val(osi_core, MACSEC_TX_PKTS_UNTG_LO_0); - mmc->tx_pkts_too_long = - update_macsec_mmc_val(osi_core, MACSEC_TX_PKTS_TOO_LONG_LO_0); - mmc->tx_octets_protected = - update_macsec_mmc_val(osi_core, MACSEC_TX_OCTETS_PRTCTD_LO_0); - mmc->rx_pkts_no_tag = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOTG_LO_0); - mmc->rx_pkts_untagged = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_UNTG_LO_0); - mmc->rx_pkts_bad_tag = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_BADTAG_LO_0); - mmc->rx_pkts_no_sa_err = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOSAERROR_LO_0); - mmc->rx_pkts_no_sa = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_NOSA_LO_0); - mmc->rx_pkts_overrun = - update_macsec_mmc_val(osi_core, MACSEC_RX_PKTS_OVRRUN_LO_0); - mmc->rx_octets_validated = - update_macsec_mmc_val(osi_core, MACSEC_RX_OCTETS_VLDTD_LO_0); - - for (i = 0; i <= OSI_SC_INDEX_MAX; i++) { - mmc->tx_pkts_protected[i] = - update_macsec_mmc_val(osi_core, - MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(i)); - mmc->rx_pkts_late[i] = - update_macsec_mmc_val(osi_core, - MACSEC_RX_PKTS_LATE_SCx_LO_0(i)); - mmc->rx_pkts_delayed[i] = mmc->rx_pkts_late[i]; - mmc->rx_pkts_not_valid[i] = - update_macsec_mmc_val(osi_core, - MACSEC_RX_PKTS_NOTVALID_SCx_LO_0(i)); - mmc->in_pkts_invalid[i] = mmc->rx_pkts_not_valid[i]; - mmc->rx_pkts_unchecked[i] = mmc->rx_pkts_not_valid[i]; - mmc->rx_pkts_ok[i] = - update_macsec_mmc_val(osi_core, - MACSEC_RX_PKTS_OK_SCx_LO_0(i)); - } -} - -/** - * @brief macsec_enable - Enable/Disable macsec Tx/Rx controller - * - * @note - * Algorithm: - * - Acquire the macsec_fpe lock - * - Return -1 if mac is mgbe and request is to enable macsec when fpe is - * already enabled - * - Enable/Disable macsec TX/RX based on the request - * - Update the is_macsec_enabled flag in osi_core accordingly - * - Release the macsec_fpe lock - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param mac, - * is_fpe_enabled, is macsec_enabled - * @param[in] enable: macsec enable or disable flag - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_enable(struct osi_core_priv_data *const osi_core, - nveu32_t enable) -{ - nveu32_t val; - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nve32_t ret = 0; - - osi_lock_irq_enabled(&osi_core->macsec_fpe_lock); - - /* MACSEC and FPE cannot coexist on MGBE refer bug 3484034 */ - if ((osi_core->mac == OSI_MAC_HW_MGBE) && - (((enable & OSI_MACSEC_TX_EN) != OSI_NONE) || - ((enable & OSI_MACSEC_RX_EN) != OSI_NONE)) && - (osi_core->is_fpe_enabled == OSI_ENABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "MACSE and FPE cannot coexist on MGBE\n", 0ULL); - ret = -1; - goto exit; - } - - val = osi_readla(osi_core, base + MACSEC_CONTROL0); - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Read MACSEC_CONTROL0: \n", val); - - if ((enable & OSI_MACSEC_TX_EN) == OSI_MACSEC_TX_EN) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Enabling macsec TX \n", 0ULL); - val |= (MACSEC_TX_EN); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Disabling macsec TX \n", 0ULL); - val &= ~(MACSEC_TX_EN); - } - - if ((enable & OSI_MACSEC_RX_EN) == OSI_MACSEC_RX_EN) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Enabling macsec RX \n", 0ULL); - val |= (MACSEC_RX_EN); - } else { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Disabling macsec RX \n", 0ULL); - val &= ~(MACSEC_RX_EN); - } - - if (((enable & OSI_MACSEC_TX_EN) != OSI_NONE) || - ((enable & OSI_MACSEC_RX_EN) != OSI_NONE)) { - osi_core->is_macsec_enabled = OSI_ENABLE; - } else { - osi_core->is_macsec_enabled = OSI_DISABLE; - } - - LOG("Write MACSEC_CONTROL0: 0x%x\n", val); - osi_writela(osi_core, val, base + MACSEC_CONTROL0); - -exit: - osi_unlock_irq_enabled(&osi_core->macsec_fpe_lock); - return ret; -} - -#ifdef MACSEC_KEY_PROGRAM -/** - * @brief poll_for_kt_update - Query the status of a KT update. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t poll_for_kt_update(struct osi_core_priv_data *osi_core) -{ - /* half sec timeout */ - nveu32_t retry = RETRY_COUNT; - nveu32_t kt_config; - nveu32_t count; - nve32_t cond = 1; - - count = 0; - while (cond == 1) { - if (count > retry) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "KT update timed out\n", - 0ULL); - return -1; - } - - count++; - - kt_config = osi_readla(osi_core, - (nveu8_t *)osi_core->tz_base + - MACSEC_GCM_KEYTABLE_CONFIG); - if ((kt_config & MACSEC_KT_CONFIG_UPDATE) == OSI_NONE) { - /* exit loop */ - cond = 0; - } else { - /* wait on UPDATE bit to reset */ - osi_core->osd_ops.udelay(RETRY_DELAY); - } - } - - return 0; -} - -static nve32_t kt_key_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) -{ - nveu32_t kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; - nveu32_t i, j; - - for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { - kt_key[i] = osi_readla(osi_core, - (nveu8_t *)osi_core->tz_base + - MACSEC_GCM_KEYTABLE_DATA(i)); - } - - if ((kt_key[MACSEC_KT_DATA_REG_CNT - 1U] & MACSEC_KT_ENTRY_VALID) == - MACSEC_KT_ENTRY_VALID) { - kt_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; - } - - for (i = 0; i < MACSEC_KT_DATA_REG_SAK_CNT; i++) { - for (j = 0; j < INTEGER_LEN; j++) { - kt_config->entry.sak[(i * 4U) + j] = - (nveu8_t)((kt_key[i] >> (j * 8U)) & 0xFFU); - } - } - - for (i = 0; i < MACSEC_KT_DATA_REG_H_CNT; i++) { - for (j = 0; j < INTEGER_LEN; j++) { - kt_config->entry.h[(i * 4U) + j] = - (nveu8_t)((kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] >> (j * 8U)) - & 0xFFU); - } - } - - return 0; -} - -static nve32_t kt_key_write(struct osi_core_priv_data *const osi_core, - const struct osi_macsec_kt_config *const kt_config) -{ - nveu32_t kt_key[MACSEC_KT_DATA_REG_CNT] = {0}; - struct osi_kt_entry entry = kt_config->entry; - nveu32_t i, j; - - /* write SAK */ - for (i = 0; i < MACSEC_KT_DATA_REG_SAK_CNT; i++) { - /* 4-bytes in each register */ - for (j = 0; j < INTEGER_LEN; j++) { - kt_key[i] |= ((nveu32_t)(entry.sak[(i * 4U) + j]) << - (j * 8U)); - } - } - /* write H-key */ - for (i = 0; i < MACSEC_KT_DATA_REG_H_CNT; i++) { - /* 4-bytes in each register */ - for (j = 0; j < INTEGER_LEN; j++) { - kt_key[i + MACSEC_KT_DATA_REG_SAK_CNT] |= - ((nveu32_t)(entry.h[(i * 4U) + j]) << (j * 8U)); - } - } - - if ((kt_config->flags & OSI_LUT_FLAGS_ENTRY_VALID) == - OSI_LUT_FLAGS_ENTRY_VALID) { - kt_key[MACSEC_KT_DATA_REG_CNT - 1U] |= MACSEC_KT_ENTRY_VALID; - } - - for (i = 0; i < MACSEC_KT_DATA_REG_CNT; i++) { - osi_writela(osi_core, kt_key[i], - (nveu8_t *)osi_core->tz_base + - MACSEC_GCM_KEYTABLE_DATA(i)); - } - - return 0; -} - -static nve32_t validate_kt_config(const struct osi_macsec_kt_config *const kt_config) -{ - /* Validate KT config */ - if ((kt_config->table_config.ctlr_sel > OSI_CTLR_SEL_MAX) || - (kt_config->table_config.rw > OSI_RW_MAX) || - (kt_config->table_config.index > OSI_TABLE_INDEX_MAX)) { - return -1; - } - return 0; - -} - -static nve32_t macsec_kt_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) -{ - nve32_t ret = 0; - nveu32_t kt_config_reg = 0; - nveu8_t *base = (nveu8_t *)osi_core->tz_base; - - ret = validate_kt_config(kt_config); - if (ret < 0) { - return ret; - } - - kt_config_reg = osi_readla(osi_core, base + MACSEC_GCM_KEYTABLE_CONFIG); - if (kt_config->table_config.ctlr_sel != OSI_NONE) { - kt_config_reg |= MACSEC_KT_CONFIG_CTLR_SEL; - } else { - kt_config_reg &= ~MACSEC_KT_CONFIG_CTLR_SEL; - } - - if (kt_config->table_config.rw != OSI_NONE) { - kt_config_reg |= MACSEC_KT_CONFIG_RW; - /* For write operation, load the lut_data registers */ - ret = kt_key_write(osi_core, kt_config); - if (ret < 0) { - return ret; - } - } else { - kt_config_reg &= ~MACSEC_KT_CONFIG_RW; - } - - kt_config_reg &= ~MACSEC_KT_CONFIG_INDEX_MASK; - kt_config_reg |= (kt_config->table_config.index); - - kt_config_reg |= MACSEC_KT_CONFIG_UPDATE; - osi_writela(osi_core, kt_config_reg, base + MACSEC_GCM_KEYTABLE_CONFIG); - - /* Wait for this KT update to finish */ - ret = poll_for_kt_update(osi_core); - if (ret < 0) { - return ret; - } - - if (kt_config->table_config.rw == OSI_NONE) { - ret = kt_key_read(osi_core, kt_config); - if (ret < 0) { - return ret; - } - } - return ret; -} -#endif /* MACSEC_KEY_PROGRAM */ - -/** - * @brief poll_for_lut_update - Query the status of a LUT update. - * - * @note - * Algorithm: - * - Check if MACSEC_LUT_CONFIG_UPDATE is reset by waiting for 1 micro second - * for 1000 iterations - * - Return -1 if maximum iterations are reached - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static inline nve32_t poll_for_lut_update(struct osi_core_priv_data *osi_core) -{ - /* half sec timeout */ - nveu32_t retry = RETRY_COUNT; - nveu32_t lut_config; - nveu32_t count; - nve32_t cond = 1; - - count = 0; - while (cond == 1) { - if (count > retry) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "LUT update timed out\n", - 0ULL); - return -1; - } - - count++; - - lut_config = osi_readla(osi_core, - (nveu8_t *)osi_core->macsec_base + - MACSEC_LUT_CONFIG); - if ((lut_config & MACSEC_LUT_CONFIG_UPDATE) == OSI_NONE) { - /* exit loop */ - cond = 0; - } else { - /* wait on UPDATE bit to reset */ - osi_core->osd_ops.udelay(RETRY_DELAY); - } - } - - return 0; -} - -/** - * @brief read_lut_data - Read LUT data - * - * @note - * Algorithm: - * - Read LUT data from MACSEC_LUT_DATA and fill lut_data buffer - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * @param[out] lut_data: Read lut_data stored in this buffer - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void read_lut_data(struct osi_core_priv_data *const osi_core, - nveu32_t *const lut_data) -{ - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t i; - - /* Commit the LUT entry to HW */ - for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { - lut_data[i] = osi_readla(osi_core, base + MACSEC_LUT_DATA(i)); - } -} - -/** - * @brief lut_read_inputs_DA - Read LUT data an fill destination address and flags - * - * @note - * Algorithm: - * - Read LUT data for mac DA and fill the flags and lut_inputs accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_data: Read lut_data stored in this buffer - * @param[out] flags: Flags to indicate if the byte is valid - * @param[out] entry: Update the DA to lut_inputs from lut_data - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_read_inputs_DA(const nveu32_t *const lut_data, - nveu32_t *flags, - struct osi_lut_inputs *const entry) -{ - /* MAC DA */ - if ((lut_data[1] & MACSEC_LUT_DA_BYTE0_INACTIVE) != - MACSEC_LUT_DA_BYTE0_INACTIVE) { - entry->da[0] = (nveu8_t)(lut_data[0] & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE0_VALID; - } - - if ((lut_data[1] & MACSEC_LUT_DA_BYTE1_INACTIVE) != - MACSEC_LUT_DA_BYTE1_INACTIVE) { - entry->da[1] = (nveu8_t)((lut_data[0] >> 8) & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE1_VALID; - } - - if ((lut_data[1] & MACSEC_LUT_DA_BYTE2_INACTIVE) != - MACSEC_LUT_DA_BYTE2_INACTIVE) { - entry->da[2] = (nveu8_t)((lut_data[0] >> 16) & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE2_VALID; - } - - if ((lut_data[1] & MACSEC_LUT_DA_BYTE3_INACTIVE) != - MACSEC_LUT_DA_BYTE3_INACTIVE) { - entry->da[3] = (nveu8_t)((lut_data[0] >> 24) & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE3_VALID; - } - - if ((lut_data[1] & MACSEC_LUT_DA_BYTE4_INACTIVE) != - MACSEC_LUT_DA_BYTE4_INACTIVE) { - entry->da[4] = (nveu8_t)(lut_data[1] & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE4_VALID; - } - - if ((lut_data[1] & MACSEC_LUT_DA_BYTE5_INACTIVE) != - MACSEC_LUT_DA_BYTE5_INACTIVE) { - entry->da[5] = (nveu8_t)((lut_data[1] >> 8) & 0xFFU); - *flags |= OSI_LUT_FLAGS_DA_BYTE5_VALID; - } - -} - -/** - * @brief lut_read_inputs_SA - Read LUT data an fill source addresss and flags - * - * @note - * Algorithm: - * - Read LUT data for mac SA and fill the flags and lut_inputs accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_data: Read lut_data stored in this buffer - * @param[out] flags: Flags to indicate if the byte is valid - * @param[out] entry: Update the SA to lut_inputs from lut_data - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_read_inputs_SA(const nveu32_t *const lut_data, - nveu32_t *flags, - struct osi_lut_inputs *const entry) -{ - /* MAC SA */ - if ((lut_data[3] & MACSEC_LUT_SA_BYTE0_INACTIVE) != - MACSEC_LUT_SA_BYTE0_INACTIVE) { - entry->sa[0] = (nveu8_t)((lut_data[1] >> 22) & 0xFFU); - *flags |= OSI_LUT_FLAGS_SA_BYTE0_VALID; - } - - if ((lut_data[3] & MACSEC_LUT_SA_BYTE1_INACTIVE) != - MACSEC_LUT_SA_BYTE1_INACTIVE) { - entry->sa[1] = (nveu8_t)((lut_data[1] >> 30) | - ((lut_data[2] & 0x3FU) << 2)); - *flags |= OSI_LUT_FLAGS_SA_BYTE1_VALID; - } - - if ((lut_data[3] & MACSEC_LUT_SA_BYTE2_INACTIVE) != - MACSEC_LUT_SA_BYTE2_INACTIVE) { - entry->sa[2] = (nveu8_t)((lut_data[2] >> 6) & 0xFFU); - *flags |= OSI_LUT_FLAGS_SA_BYTE2_VALID; - } - - if ((lut_data[3] & MACSEC_LUT_SA_BYTE3_INACTIVE) != - MACSEC_LUT_SA_BYTE3_INACTIVE) { - entry->sa[3] = (nveu8_t)((lut_data[2] >> 14) & 0xFFU); - *flags |= OSI_LUT_FLAGS_SA_BYTE3_VALID; - } - - if ((lut_data[3] & MACSEC_LUT_SA_BYTE4_INACTIVE) != - MACSEC_LUT_SA_BYTE4_INACTIVE) { - entry->sa[4] = (nveu8_t)((lut_data[2] >> 22) & 0xFFU); - *flags |= OSI_LUT_FLAGS_SA_BYTE4_VALID; - } - - if ((lut_data[3] & MACSEC_LUT_SA_BYTE5_INACTIVE) != - MACSEC_LUT_SA_BYTE5_INACTIVE) { - entry->sa[5] = (nveu8_t)((lut_data[2] >> 30) | - ((lut_data[3] & 0x3FU) << 2)); - *flags |= OSI_LUT_FLAGS_SA_BYTE5_VALID; - } - -} - -/** - * @brief lut_read_inputs_vlan - Read LUT data and fill VLAN fields and flags - * - * @note - * Algorithm: - * - Read LUT data for mac VLAN PCP and ID and fill the flags and - * lut_inputs accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_data: Read lut_data stored in this buffer - * @param[out] flags: Flags to indicate if the byte is valid - * @param[out] entry: Update the vlan_pcp and vlan_id to lut_inputs from lut_data - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_read_inputs_vlan(const nveu32_t *const lut_data, - nveu32_t *flags, - struct osi_lut_inputs *const entry) -{ - /* VLAN */ - if ((lut_data[4] & MACSEC_LUT_VLAN_ACTIVE) == MACSEC_LUT_VLAN_ACTIVE) { - *flags |= OSI_LUT_FLAGS_VLAN_VALID; - /* VLAN PCP */ - if ((lut_data[4] & MACSEC_LUT_VLAN_PCP_INACTIVE) != - MACSEC_LUT_VLAN_PCP_INACTIVE) { - *flags |= OSI_LUT_FLAGS_VLAN_PCP_VALID; - entry->vlan_pcp = lut_data[3] >> 29U; - } - - /* VLAN ID */ - if ((lut_data[4] & MACSEC_LUT_VLAN_ID_INACTIVE) != - MACSEC_LUT_VLAN_ID_INACTIVE) { - *flags |= OSI_LUT_FLAGS_VLAN_ID_VALID; - entry->vlan_id = (lut_data[4] >> 1) & 0xFFFU; - } - } -} - -/** - * @brief lut_read_inputs - Read LUT data and fill lut_inputs accordingly - * - * @note - * Algorithm: - * - Read LUT data and fill the flags and lut_inputs accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_data: Read lut_data stored in this buffer - * @param[out] lut_config: Update the lut_config from lut_data - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t lut_read_inputs(struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = {0}; - nveu32_t flags = 0; - - lut_read_inputs_DA(lut_data, &flags, &entry); - lut_read_inputs_SA(lut_data, &flags, &entry); - - /* Ether type */ - if ((lut_data[3] & MACSEC_LUT_ETHTYPE_INACTIVE) != - MACSEC_LUT_ETHTYPE_INACTIVE) { - entry.ethtype[0] = (nveu8_t)((lut_data[3] >> 12) & (0xFFU)); - entry.ethtype[1] = (nveu8_t)((lut_data[3] >> 20) & (0xFFU)); - flags |= OSI_LUT_FLAGS_ETHTYPE_VALID; - } - - lut_read_inputs_vlan(lut_data, &flags, &entry); - - /* Byte patterns */ - if ((lut_data[4] & MACSEC_LUT_BYTE0_PATTERN_INACTIVE) != - MACSEC_LUT_BYTE0_PATTERN_INACTIVE) { - flags |= OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; - entry.byte_pattern[0] = (nveu8_t)((lut_data[4] >> 15) & 0xFFU); - entry.byte_pattern_offset[0] = (nveu8_t)((lut_data[4] >> 23) & - 0x3FU); - } - if ((lut_data[5] & MACSEC_LUT_BYTE1_PATTERN_INACTIVE) != - MACSEC_LUT_BYTE1_PATTERN_INACTIVE) { - flags |= OSI_LUT_FLAGS_BYTE1_PATTERN_VALID; - entry.byte_pattern[1] = (nveu8_t)((lut_data[4] >> 30) | - ((lut_data[5] & 0x3FU) << 2)); - entry.byte_pattern_offset[1] = (nveu8_t)((lut_data[5] >> 6) & - 0x3FU); - } - if ((lut_data[5] & MACSEC_LUT_BYTE2_PATTERN_INACTIVE) != - MACSEC_LUT_BYTE2_PATTERN_INACTIVE) { - flags |= OSI_LUT_FLAGS_BYTE2_PATTERN_VALID; - entry.byte_pattern[2] = (nveu8_t)((lut_data[5] >> 13) & 0xFFU); - entry.byte_pattern_offset[2] = (nveu8_t)((lut_data[5] >> 21) & - 0x3FU); - } - if ((lut_data[6] & MACSEC_LUT_BYTE3_PATTERN_INACTIVE) != - MACSEC_LUT_BYTE3_PATTERN_INACTIVE) { - flags |= OSI_LUT_FLAGS_BYTE3_PATTERN_VALID; - entry.byte_pattern[3] = (nveu8_t)((lut_data[5] >> 28) | - ((lut_data[6] & 0xFU) << 4)); - entry.byte_pattern_offset[3] = (nveu8_t)((lut_data[6] >> 4) & - 0x3FU); - } - - /* Preempt mask */ - if ((lut_data[6] & MACSEC_LUT_PREEMPT_INACTIVE) != - MACSEC_LUT_PREEMPT_INACTIVE) { - flags |= OSI_LUT_FLAGS_PREEMPT_VALID; - if ((lut_data[6] & MACSEC_LUT_PREEMPT) == MACSEC_LUT_PREEMPT) { - flags |= OSI_LUT_FLAGS_PREEMPT; - } - } - - lut_config->lut_in = entry; - lut_config->flags = flags; - - return 0; -} - -/** - * @brief byp_lut_read - Read BYP LUT data and fill lut_config accordingly - * - * @note - * Algorithm: - * - Read LUT data and fill the flags and lut_config accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * @param[out] lut_config: Update the lut_config from BYP LUT - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t byp_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - nveu32_t flags = 0, val = 0; - nveu32_t index = lut_config->table_config.index; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu8_t *paddr = OSI_NULL; - nve32_t ret = 0; - - read_lut_data(osi_core, lut_data); - - if (lut_read_inputs(lut_config, lut_data) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "LUT inputs error\n", 0ULL); - return -1; - } - - /* Lookup output */ - if ((lut_data[6] & MACSEC_LUT_CONTROLLED_PORT) == - MACSEC_LUT_CONTROLLED_PORT) { - flags |= OSI_LUT_FLAGS_CONTROLLED_PORT; - } - - if ((lut_data[6] & MACSEC_BYP_LUT_DVLAN_PKT) == - MACSEC_BYP_LUT_DVLAN_PKT) { - flags |= OSI_LUT_FLAGS_DVLAN_PKT; - } - - if ((lut_data[6] & BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL) == - BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL) { - flags |= OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; - } - - switch (lut_config->table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - paddr = addr + MACSEC_TX_BYP_LUT_VALID; - break; - case OSI_CTLR_SEL_RX: - paddr = addr + MACSEC_RX_BYP_LUT_VALID; - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller select\n", 0ULL); - ret = -1; - break; - } - if (ret == OSI_NONE_SIGNED) { - val = osi_readla(osi_core, paddr); - if ((val & ((nveu32_t)(1U) << (index & 0x1FU))) != OSI_NONE) { - flags |= OSI_LUT_FLAGS_ENTRY_VALID; - } - lut_config->flags |= flags; - } - return ret; -} - -/** - * @brief tx_sci_lut_read - Read LUT_data and fill tx sci lut_config accordingly - * - * @note - * Algorithm: - * - Read LUT data and fill the flags and lut_config accordingly - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * @param[in] lut_data: lut_data read from h/w registers - * @param[out] lut_config: Update the lut_config from lut_data - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void tx_sci_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config, - const nveu32_t *const lut_data) -{ - nveu32_t val = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t index = lut_config->table_config.index; - - if ((lut_data[6] & MACSEC_LUT_AN0_VALID) == - MACSEC_LUT_AN0_VALID) { - lut_config->sci_lut_out.an_valid |= OSI_AN0_VALID; - } - if ((lut_data[6] & MACSEC_LUT_AN1_VALID) == - MACSEC_LUT_AN1_VALID) { - lut_config->sci_lut_out.an_valid |= OSI_AN1_VALID; - } - if ((lut_data[6] & MACSEC_LUT_AN2_VALID) == - MACSEC_LUT_AN2_VALID) { - lut_config->sci_lut_out.an_valid |= OSI_AN2_VALID; - } - if ((lut_data[6] & MACSEC_LUT_AN3_VALID) == - MACSEC_LUT_AN3_VALID) { - lut_config->sci_lut_out.an_valid |= OSI_AN3_VALID; - } - - lut_config->sci_lut_out.sc_index = (lut_data[6] >> 17) & 0xFU; - - if ((lut_data[6] & MACSEC_TX_SCI_LUT_DVLAN_PKT) == - MACSEC_TX_SCI_LUT_DVLAN_PKT) { - lut_config->flags |= OSI_LUT_FLAGS_DVLAN_PKT; - } - if ((lut_data[6] & MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) == - MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL) { - lut_config->flags |= - OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL; - } - - val = osi_readla(osi_core, addr+MACSEC_TX_SCI_LUT_VALID); - if ((val & ((nveu32_t)(1U) << (index & 0xFFU))) != OSI_NONE) { - lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; - } -} - -/** - * @brief sci_lut_read - Read SCI LUT data - * - * @note - * Algorithm: - * - Return -1 if the index is not valid - * - Read SCI Lut data from h/w registers to lut_data - * - Read Tx/Rx SCI lut data - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. Used param macsec_base - * @param[out] lut_config: Update the lut_config from h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sci_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - nveu32_t flags = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t val = 0; - nveu32_t index = lut_config->table_config.index; - nve32_t ret = 0; - - if (index > OSI_SC_LUT_MAX_INDEX) { - return -1; - } - read_lut_data(osi_core, lut_data); - - switch (lut_config->table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - if (lut_read_inputs(lut_config, lut_data) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "LUT inputs error\n", 0ULL); - return -1; - } - tx_sci_lut_read(osi_core, lut_config, lut_data); - break; - case OSI_CTLR_SEL_RX: - lut_config->sci_lut_out.sci[0] = (nveu8_t)(lut_data[0] & 0xFFU); - lut_config->sci_lut_out.sci[1] = (nveu8_t)((lut_data[0] >> 8) & 0xFFU); - lut_config->sci_lut_out.sci[2] = (nveu8_t)((lut_data[0] >> 16) & 0xFFU); - lut_config->sci_lut_out.sci[3] = (nveu8_t)((lut_data[0] >> 24) & 0xFFU); - lut_config->sci_lut_out.sci[4] = (nveu8_t)(lut_data[1] & 0xFFU); - lut_config->sci_lut_out.sci[5] = (nveu8_t)((lut_data[1] >> 8) & 0xFFU); - lut_config->sci_lut_out.sci[6] = (nveu8_t)((lut_data[1] >> 16) & 0xFFU); - lut_config->sci_lut_out.sci[7] = (nveu8_t)((lut_data[1] >> 24) & 0xFFU); - - lut_config->sci_lut_out.sc_index = (lut_data[2] >> 10) & 0xFU; - if ((lut_data[2] & MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE) != - MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE) { - flags |= OSI_LUT_FLAGS_PREEMPT_VALID; - if ((lut_data[2] & MACSEC_RX_SCI_LUT_PREEMPT) == - MACSEC_RX_SCI_LUT_PREEMPT) { - flags |= OSI_LUT_FLAGS_PREEMPT; - } - } - - val = osi_readla(osi_core, addr+MACSEC_RX_SCI_LUT_VALID); - if ((val & ((nveu32_t)(1U) << index)) != OSI_NONE) { - lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; - } - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller selected\n", 0ULL); - ret = -1; - break; - } - - /* Lookup output */ - return ret; -} - -/** - * @brief sc_param_lut_read - Read SC Param LUT data - * - * @note - * Algorithm: - * - Read SC param Lut data from h/w registers to lut_data - * - Update the Tx/Rx SC param data to lut_config - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] lut_config: Update the lut_config from h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sc_param_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - nve32_t ret = 0; - - read_lut_data(osi_core, lut_data); - - switch (lut_config->table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1FU; - lut_config->sc_param_out.pn_max = (lut_data[0] >> 5) | - (lut_data[1] << 27); - lut_config->sc_param_out.pn_threshold = (lut_data[1] >> 5) | - (lut_data[2] << 27); - lut_config->sc_param_out.tci = (nveu8_t)((lut_data[2] >> 5) & 0x3U); - lut_config->sc_param_out.sci[0] = (nveu8_t)((lut_data[2] >> 8) & 0xFFU); - lut_config->sc_param_out.sci[1] = (nveu8_t)((lut_data[2] >> 16) & 0xFFU); - lut_config->sc_param_out.sci[2] = (nveu8_t)((lut_data[2] >> 24) & 0xFFU); - lut_config->sc_param_out.sci[3] = (nveu8_t)(lut_data[3] & 0xFFU); - lut_config->sc_param_out.sci[4] = (nveu8_t)((lut_data[3] >> 8) & 0xFFU); - lut_config->sc_param_out.sci[5] = (nveu8_t)((lut_data[3] >> 16) & 0xFFU); - lut_config->sc_param_out.sci[6] = (nveu8_t)((lut_data[3] >> 24) & 0xFFU); - lut_config->sc_param_out.sci[7] = (nveu8_t)(lut_data[4] & 0xFFU); - lut_config->sc_param_out.vlan_in_clear = - (nveu8_t)((lut_data[4] >> 8) & 0x1U); - break; - case OSI_CTLR_SEL_RX: - lut_config->sc_param_out.key_index_start = lut_data[0] & 0x1FU; - lut_config->sc_param_out.pn_window = (lut_data[0] >> 5) | - (lut_data[1] << 27); - lut_config->sc_param_out.pn_max = (lut_data[1] >> 5) | - (lut_data[2] << 27); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller selected\n", 0ULL); - ret = -1; - break; - } - - /* Lookup output */ - return ret; -} - -/** - * @brief sc_state_lut_read - Read SC state LUT data - * - * @note - * Algorithm: - * - Read SC state Lut data from h/w registers to lut_data - * - Update the curr_an to lut_config - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] lut_config: Update the lut_config from h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sc_state_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - - read_lut_data(osi_core, lut_data); - lut_config->sc_state_out.curr_an = lut_data[0]; - - return 0; -} - -/** - * @brief sa_state_lut_read - Read Sa state LUT data - * - * @note - * Algorithm: - * - Read Sa state Lut data from h/w registers to lut_data - * - Update the flags and next_pn and lowest_pn to lut_config for TX/RX - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] lut_config: Update the lut_config from h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sa_state_lut_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - nve32_t ret = 0; - - read_lut_data(osi_core, lut_data); - - switch (lut_config->table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - lut_config->sa_state_out.next_pn = lut_data[0]; - if ((lut_data[1] & MACSEC_SA_STATE_LUT_ENTRY_VALID) == - MACSEC_SA_STATE_LUT_ENTRY_VALID) { - lut_config->flags |= OSI_LUT_FLAGS_ENTRY_VALID; - } - break; - case OSI_CTLR_SEL_RX: - lut_config->sa_state_out.next_pn = lut_data[0]; - lut_config->sa_state_out.lowest_pn = lut_data[1]; - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller selected\n", 0ULL); - ret = -1; - break; - } - - /* Lookup output */ - return ret; -} - -/** - * @brief lut_data_read - Read different types of LUT data - * - * @note - * Algorithm: - * - Read byp/SCI/SC param/SC state/SA state lut data to lut_config - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[out] lut_config: Update the lut_config from h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t lut_data_read(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nve32_t ret = 0; - - switch (lut_config->lut_sel) { - case OSI_LUT_SEL_BYPASS: - ret = byp_lut_read(osi_core, lut_config); - break; - case OSI_LUT_SEL_SCI: - ret = sci_lut_read(osi_core, lut_config); - break; - case OSI_LUT_SEL_SC_PARAM: - ret = sc_param_lut_read(osi_core, lut_config); - break; - case OSI_LUT_SEL_SC_STATE: - ret = sc_state_lut_read(osi_core, lut_config); - break; - case OSI_LUT_SEL_SA_STATE: - ret = sa_state_lut_read(osi_core, lut_config); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unsupported LUT\n", 0ULL); - ret = -1; - break; - } - - return ret; -} - -/** - * @brief commit_lut_data - Write lut_data to h/w registers - * - * @note - * Algorithm: - * - Write lut_data to h/w registers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lut_data: data to be pushed to h/w registers - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void commit_lut_data(struct osi_core_priv_data *const osi_core, - nveu32_t const *const lut_data) -{ - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t i; - - /* Commit the LUT entry to HW */ - for (i = 0; i < MACSEC_LUT_DATA_REG_CNT; i++) { - osi_writela(osi_core, lut_data[i], base + MACSEC_LUT_DATA(i)); - } -} - -/** - * @brief rx_sa_state_lut_config - update lut_data from lut_config sa_state - * - * @note - * Algorithm: - * - update lut_data from lut_config sa_state - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: sa_state from lut_config is used. Param used sa_state_out - * @param[out] lut_data: buffer to which sa_state is updated - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void rx_sa_state_lut_config( - const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_sa_state_outputs entry = lut_config->sa_state_out; - - lut_data[0] |= entry.next_pn; - lut_data[1] |= entry.lowest_pn; -} - -/** - * @brief tx_sa_state_lut_config - update lut_data from lut_config sa_state - * - * @note - * Algorithm: - * - update lut_data from lut_config sa_state - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: sa_state from lut_config is used. Param used sa_state_out - * @param[out] lut_data: buffer to which sa_state is updated - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void tx_sa_state_lut_config(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - nveu32_t flags = lut_config->flags; - struct osi_sa_state_outputs entry = lut_config->sa_state_out; - - lut_data[0] |= entry.next_pn; - if ((flags & OSI_LUT_FLAGS_ENTRY_VALID) == OSI_LUT_FLAGS_ENTRY_VALID) { - lut_data[1] |= MACSEC_SA_STATE_LUT_ENTRY_VALID; - } - -} - -/** - * @brief sa_state_lut_config - update lut_data from lut_config sa_state - * - * @note - * Algorithm: - * - update lut_data from lut_config sa_state for Tx/Rx - * - program the lut_data to h/w - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lut_config: sa_state from lut_config is used. Param used table_config - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sa_state_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct osi_macsec_table_config table_config = lut_config->table_config; - nve32_t ret = 0; - - switch (table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - tx_sa_state_lut_config(lut_config, lut_data); - break; - case OSI_CTLR_SEL_RX: - rx_sa_state_lut_config(lut_config, lut_data); - break; - default: - ret = -1; - break; - } - - commit_lut_data(osi_core, lut_data); - - return ret; -} - -/** - * @brief sc_state_lut_config - update lut_data from lut_config sc_state - * - * @note - * Algorithm: - * - update lut_data from lut_config sc_state for Tx/Rx - * - program the lut_data to h/w - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lut_config: sc_state from lut_config is used. Param used sc_state_out - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sc_state_lut_config(struct osi_core_priv_data *const osi_core, - const struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct osi_sc_state_outputs entry = lut_config->sc_state_out; - - lut_data[0] |= entry.curr_an; - commit_lut_data(osi_core, lut_data); - - return 0; -} - -/** - * @brief rx_sc_param_lut_config - update lut_data from lut_config rx_sc_param - * - * @note - * Algorithm: - * - update lut_data from lut_config sc_param for Rx - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: sa_state from lut_config is used. Param used sc_param_out - * @param[out] lut_data: rx_sc_params are updated to lut_data buffer - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void rx_sc_param_lut_config( - const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_sc_param_outputs entry = lut_config->sc_param_out; - - lut_data[0] |= entry.key_index_start; - lut_data[0] |= entry.pn_window << 5; - lut_data[1] |= entry.pn_window >> 27; - lut_data[1] |= entry.pn_max << 5; - lut_data[2] |= entry.pn_max >> 27; -} - -/** - * @brief tx_sc_param_lut_config - update lut_data from lut_config tx_sc_param - * - * @note - * Algorithm: - * - update lut_data from lut_config sc_param for Tx - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: sa_state from lut_config is used. Param used sc_param_out - * @param[out] lut_data: tx_sc_params are updated to lut_data buffer - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void tx_sc_param_lut_config( - const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_sc_param_outputs entry = lut_config->sc_param_out; - - lut_data[0] |= entry.key_index_start; - lut_data[0] |= entry.pn_max << 5; - lut_data[1] |= entry.pn_max >> 27; - lut_data[1] |= entry.pn_threshold << 5; - lut_data[2] |= entry.pn_threshold >> 27; - lut_data[2] |= (nveu32_t)(entry.tci) << 5; - lut_data[2] |= ((nveu32_t)entry.sci[0]) << 8; - lut_data[2] |= ((nveu32_t)entry.sci[1]) << 16; - lut_data[2] |= ((nveu32_t)entry.sci[2]) << 24; - lut_data[3] |= ((nveu32_t)entry.sci[3]); - lut_data[3] |= ((nveu32_t)entry.sci[4]) << 8; - lut_data[3] |= ((nveu32_t)entry.sci[5]) << 16; - lut_data[3] |= ((nveu32_t)entry.sci[6]) << 24; - lut_data[4] |= ((nveu32_t)entry.sci[7]); - lut_data[4] |= ((nveu32_t)entry.vlan_in_clear) << 8; -} - -/** - * @brief sc_param_lut_config - update lut_data from lut_config sc_param - * - * @note - * Algorithm: - * - Return -1 for invalid index - * - update lut_data from lut_config sc_param for Tx/Rx - * - commit the lut_data to h/w - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lut_config: sc_param from lut_config is used. Param used sc_param_out - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sc_param_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct osi_macsec_table_config table_config = lut_config->table_config; - struct osi_sc_param_outputs entry = lut_config->sc_param_out; - nve32_t ret = 0; - - if (entry.key_index_start > OSI_KEY_INDEX_MAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalid Key Index\n", 0ULL); - return -1; - } - - switch (table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - tx_sc_param_lut_config(lut_config, lut_data); - break; - case OSI_CTLR_SEL_RX: - rx_sc_param_lut_config(lut_config, lut_data); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller selected\n", 0ULL); - ret = -1; - break; - } - - commit_lut_data(osi_core, lut_data); - - return ret; -} - -/** - * @brief lut_config_MAC_SA - update lut_data from lut_config source address - * - * @note - * Algorithm: - * - update lut_data from lut_config mac_SA and flags - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: mac SA from lut_config is used. Param used lut_in - * @param[out] lut_data: lut_data is updated with MAC SA - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_MAC_SA(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - - /* MAC SA */ - if ((flags & OSI_LUT_FLAGS_SA_BYTE0_VALID) == - OSI_LUT_FLAGS_SA_BYTE0_VALID) { - lut_data[1] |= ((nveu32_t)entry.sa[0]) << 22; - lut_data[3] &= ~MACSEC_LUT_SA_BYTE0_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE0_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_SA_BYTE1_VALID) == - OSI_LUT_FLAGS_SA_BYTE1_VALID) { - lut_data[1] |= ((nveu32_t)entry.sa[1]) << 30; - lut_data[2] |= (((nveu32_t)(entry.sa[1])) >> 2); - lut_data[3] &= ~MACSEC_LUT_SA_BYTE1_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE1_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_SA_BYTE2_VALID) == - OSI_LUT_FLAGS_SA_BYTE2_VALID) { - lut_data[2] |= ((nveu32_t)entry.sa[2]) << 6; - lut_data[3] &= ~MACSEC_LUT_SA_BYTE2_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE2_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_SA_BYTE3_VALID) == - OSI_LUT_FLAGS_SA_BYTE3_VALID) { - lut_data[2] |= ((nveu32_t)entry.sa[3]) << 14; - lut_data[3] &= ~MACSEC_LUT_SA_BYTE3_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE3_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_SA_BYTE4_VALID) == - OSI_LUT_FLAGS_SA_BYTE4_VALID) { - lut_data[2] |= ((nveu32_t)(entry.sa[4])) << 22; - lut_data[3] &= ~MACSEC_LUT_SA_BYTE4_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE4_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_SA_BYTE5_VALID) == - OSI_LUT_FLAGS_SA_BYTE5_VALID) { - lut_data[2] |= ((nveu32_t)entry.sa[5]) << 30; - lut_data[3] |= (((nveu32_t)entry.sa[5]) >> 2); - lut_data[3] &= ~MACSEC_LUT_SA_BYTE5_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_SA_BYTE5_INACTIVE; - } - -} - -/** - * @brief lut_config_MAC_DA - update lut_data from lut_config destination address - * - * @note - * Algorithm: - * - update lut_data from lut_config mac_DA and flags - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: mac DA from lut_config is used. Param used lut_in - * @param[out] lut_data: lut_data is updated with MAC DA - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_MAC_DA(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - - /* MAC DA */ - if ((flags & OSI_LUT_FLAGS_DA_BYTE0_VALID) == - OSI_LUT_FLAGS_DA_BYTE0_VALID) { - lut_data[0] |= ((nveu32_t)entry.da[0]); - lut_data[1] &= ~MACSEC_LUT_DA_BYTE0_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE0_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_DA_BYTE1_VALID) == - OSI_LUT_FLAGS_DA_BYTE1_VALID) { - lut_data[0] |= ((nveu32_t)entry.da[1]) << 8; - lut_data[1] &= ~MACSEC_LUT_DA_BYTE1_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE1_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_DA_BYTE2_VALID) == - OSI_LUT_FLAGS_DA_BYTE2_VALID) { - lut_data[0] |= ((nveu32_t)entry.da[2]) << 16; - lut_data[1] &= ~MACSEC_LUT_DA_BYTE2_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE2_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_DA_BYTE3_VALID) == - OSI_LUT_FLAGS_DA_BYTE3_VALID) { - lut_data[0] |= ((nveu32_t)entry.da[3]) << 24; - lut_data[1] &= ~MACSEC_LUT_DA_BYTE3_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE3_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_DA_BYTE4_VALID) == - OSI_LUT_FLAGS_DA_BYTE4_VALID) { - lut_data[1] |= ((nveu32_t)entry.da[4]); - lut_data[1] &= ~MACSEC_LUT_DA_BYTE4_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE4_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_DA_BYTE5_VALID) == - OSI_LUT_FLAGS_DA_BYTE5_VALID) { - lut_data[1] |= ((nveu32_t)entry.da[5]) << 8; - lut_data[1] &= ~MACSEC_LUT_DA_BYTE5_INACTIVE; - } else { - lut_data[1] |= MACSEC_LUT_DA_BYTE5_INACTIVE; - } - -} - -/** - * @brief lut_config_ether_type - update lut_data from lut_config ether type - * - * @note - * Algorithm: - * - update lut_data from lut_config ether_type and flags - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: ether_type from lut_config is used. Param used lut_in - * @param[out] lut_data: lut_data is updated with ether_type - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_ether_type(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - - /* Ether type */ - if ((flags & OSI_LUT_FLAGS_ETHTYPE_VALID) == - OSI_LUT_FLAGS_ETHTYPE_VALID) { - lut_data[3] |= ((nveu32_t)entry.ethtype[0]) << 12; - lut_data[3] |= ((nveu32_t)entry.ethtype[1]) << 20; - lut_data[3] &= ~MACSEC_LUT_ETHTYPE_INACTIVE; - } else { - lut_data[3] |= MACSEC_LUT_ETHTYPE_INACTIVE; - } -} - -/** - * @brief lut_config_vlan - update lut_data from lut_config vlan params - * - * @note - * Algorithm: - * - update lut_data from lut_config vlan pcp, id and flags - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: vlan params from lut_config is used. Param used lut_in - * @param[out] lut_data: lut_data is updated with vlan params - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_vlan(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - - /* VLAN */ - if ((flags & OSI_LUT_FLAGS_VLAN_VALID) == OSI_LUT_FLAGS_VLAN_VALID) { - /* VLAN PCP */ - if ((flags & OSI_LUT_FLAGS_VLAN_PCP_VALID) == - OSI_LUT_FLAGS_VLAN_PCP_VALID) { - lut_data[3] |= entry.vlan_pcp << 29; - lut_data[4] &= ~MACSEC_LUT_VLAN_PCP_INACTIVE; - } else { - lut_data[4] |= MACSEC_LUT_VLAN_PCP_INACTIVE; - } - - /* VLAN ID */ - if ((flags & OSI_LUT_FLAGS_VLAN_ID_VALID) == - OSI_LUT_FLAGS_VLAN_ID_VALID) { - lut_data[4] |= entry.vlan_id << 1; - lut_data[4] &= ~MACSEC_LUT_VLAN_ID_INACTIVE; - } else { - lut_data[4] |= MACSEC_LUT_VLAN_ID_INACTIVE; - } - lut_data[4] |= MACSEC_LUT_VLAN_ACTIVE; - } else { - lut_data[4] |= MACSEC_LUT_VLAN_PCP_INACTIVE; - lut_data[4] |= MACSEC_LUT_VLAN_ID_INACTIVE; - lut_data[4] &= ~MACSEC_LUT_VLAN_ACTIVE; - } -} - -/** - * @brief lut_config_byte_pattern - update lut_data from lut_config byte pattern - * - * @note - * Algorithm: - * - update lut_data from lut_config byte pattern and flags for 4 bytes - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: byte pattern from lut_config is used. Param used lut_in - * @param[out] lut_data: lut_data is updated with byte patterns - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_byte_pattern(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - - /* Byte patterns */ - if ((flags & OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) == - OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) { - lut_data[4] |= ((nveu32_t)entry.byte_pattern[0]) << 15; - lut_data[4] |= entry.byte_pattern_offset[0] << 23; - lut_data[4] &= ~MACSEC_LUT_BYTE0_PATTERN_INACTIVE; - } else { - lut_data[4] |= MACSEC_LUT_BYTE0_PATTERN_INACTIVE; - } - if ((flags & OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) == - OSI_LUT_FLAGS_BYTE1_PATTERN_VALID) { - lut_data[4] |= ((nveu32_t)entry.byte_pattern[1]) << 30; - lut_data[5] |= ((nveu32_t)entry.byte_pattern[1]) >> 2; - lut_data[5] |= entry.byte_pattern_offset[1] << 6; - lut_data[5] &= ~MACSEC_LUT_BYTE1_PATTERN_INACTIVE; - } else { - lut_data[5] |= MACSEC_LUT_BYTE1_PATTERN_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) == - OSI_LUT_FLAGS_BYTE2_PATTERN_VALID) { - lut_data[5] |= ((nveu32_t)entry.byte_pattern[2]) << 13; - lut_data[5] |= entry.byte_pattern_offset[2] << 21; - lut_data[5] &= ~MACSEC_LUT_BYTE2_PATTERN_INACTIVE; - } else { - lut_data[5] |= MACSEC_LUT_BYTE2_PATTERN_INACTIVE; - } - - if ((flags & OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) == - OSI_LUT_FLAGS_BYTE3_PATTERN_VALID) { - lut_data[5] |= ((nveu32_t)entry.byte_pattern[3]) << 28; - lut_data[6] |= ((nveu32_t)entry.byte_pattern[3]) >> 4; - lut_data[6] |= entry.byte_pattern_offset[3] << 4; - lut_data[6] &= ~MACSEC_LUT_BYTE3_PATTERN_INACTIVE; - } else { - lut_data[6] |= MACSEC_LUT_BYTE3_PATTERN_INACTIVE; - } -} - -/** - * @brief lut_config_preempt_mask - update lut_data from lut_config preempt mask - * - * @note - * Algorithm: - * - update lut_data from lut_config preempt mask and flags - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: preempt mask from lut_config is used. - * @param[out] lut_data: lut_data is updated with preempt mask - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void lut_config_preempt_mask(const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - nveu32_t flags = lut_config->flags; - - /* Preempt mask */ - if ((flags & OSI_LUT_FLAGS_PREEMPT_VALID) == - OSI_LUT_FLAGS_PREEMPT_VALID) { - if ((flags & OSI_LUT_FLAGS_PREEMPT) == OSI_LUT_FLAGS_PREEMPT) { - lut_data[6] |= MACSEC_LUT_PREEMPT; - } else { - lut_data[6] &= ~MACSEC_LUT_PREEMPT; - } - lut_data[6] &= ~MACSEC_LUT_PREEMPT_INACTIVE; - } else { - lut_data[6] |= MACSEC_LUT_PREEMPT_INACTIVE; - } -} - -/** - * @brief lut_config_inputs - update lut_data from lut_config attributes - * - * @note - * Algorithm: - * - Return -1 for invalid byte pattern offset - * - Return -1 for invalid vlan params - * - update the lut_data with mac_DA, mac_SA, ether_type, - * vlan params, byte_pattern and preempt mask - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used. - * @param[out] lut_data: lut_data is updated with attributes from lut_config - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t lut_config_inputs(struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - struct osi_lut_inputs entry = lut_config->lut_in; - nveu32_t flags = lut_config->flags; - nveu32_t i, j = OSI_LUT_FLAGS_BYTE0_PATTERN_VALID; - - for (i = 0; i < OSI_LUT_BYTE_PATTERN_MAX; i++) { - if ((flags & j) == j) { - if (entry.byte_pattern_offset[i] > - OSI_LUT_BYTE_PATTERN_MAX_OFFSET) { - return -1; - } - } - j <<= 1; - } - - if ((flags & OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) == - OSI_LUT_FLAGS_BYTE0_PATTERN_VALID) { - if (entry.byte_pattern_offset[0] > - OSI_LUT_BYTE_PATTERN_MAX_OFFSET) { - return -1; - } - } - - if ((flags & OSI_LUT_FLAGS_VLAN_VALID) == OSI_LUT_FLAGS_VLAN_VALID) { - if ((entry.vlan_pcp > OSI_VLAN_PCP_MAX) || - (entry.vlan_id > OSI_VLAN_ID_MAX)) { - return -1; - } - } - - lut_config_MAC_DA(lut_config, lut_data); - lut_config_MAC_SA(lut_config, lut_data); - lut_config_ether_type(lut_config, lut_data); - lut_config_vlan(lut_config, lut_data); - lut_config_byte_pattern(lut_config, lut_data); - lut_config_preempt_mask(lut_config, lut_data); - - return 0; -} - -/** - * @brief rx_sci_lut_config - update lut_data from lut_config for sci_lut - * - * @note - * Algorithm: - * - Return -1 for invalid sc_index - * - update the lut_data with sci, preempt mask and index - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used. - * @param[out] lut_data: lut_data is updated with attributes from lut_config - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t rx_sci_lut_config( - const struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - nveu32_t flags = lut_config->flags; - struct osi_sci_lut_outputs entry = lut_config->sci_lut_out; - - if (entry.sc_index > OSI_SC_INDEX_MAX) { - return -1; - } - - lut_data[0] |= ((nveu32_t)(entry.sci[0]) | - (((nveu32_t)entry.sci[1]) << 8) | - (((nveu32_t)entry.sci[2]) << 16) | - (((nveu32_t)entry.sci[3]) << 24)); - lut_data[1] |= (((nveu32_t)entry.sci[4]) | - (((nveu32_t)entry.sci[5]) << 8) | - (((nveu32_t)entry.sci[6]) << 16) | - (((nveu32_t)entry.sci[7]) << 24)); - - /* Preempt mask */ - if ((flags & OSI_LUT_FLAGS_PREEMPT_VALID) == - OSI_LUT_FLAGS_PREEMPT_VALID) { - if ((flags & OSI_LUT_FLAGS_PREEMPT) == OSI_LUT_FLAGS_PREEMPT) { - lut_data[2] |= MACSEC_RX_SCI_LUT_PREEMPT; - } else { - lut_data[2] &= ~MACSEC_RX_SCI_LUT_PREEMPT; - } - lut_data[2] &= ~MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE; - } else { - lut_data[2] |= MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE; - } - - lut_data[2] |= entry.sc_index << 10; - - return 0; -} - -/** - * @brief rx_sci_lut_config - update lut_data from lut_config for sci_lut - * - * @note - * Algorithm: - * - update the lut_data with inputs such as DA, SA, ether_type and other params - * - Update valid an mask in lut_data - * - Update dvlan tags in lut_data - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used. - * @param[out] lut_data: lut_data is updated with attributes from lut_config - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t tx_sci_lut_config( - struct osi_macsec_lut_config *const lut_config, - nveu32_t *const lut_data) -{ - nveu32_t flags = lut_config->flags; - struct osi_sci_lut_outputs entry = lut_config->sci_lut_out; - nveu32_t an_valid = entry.an_valid; - - if (lut_config_inputs(lut_config, lut_data) != 0) { - return -1; - } - - /* Lookup result fields */ - if ((an_valid & OSI_AN0_VALID) == OSI_AN0_VALID) { - lut_data[6] |= MACSEC_LUT_AN0_VALID; - } - if ((an_valid & OSI_AN1_VALID) == OSI_AN1_VALID) { - lut_data[6] |= MACSEC_LUT_AN1_VALID; - } - if ((an_valid & OSI_AN2_VALID) == OSI_AN2_VALID) { - lut_data[6] |= MACSEC_LUT_AN2_VALID; - } - if ((an_valid & OSI_AN3_VALID) == OSI_AN3_VALID) { - lut_data[6] |= MACSEC_LUT_AN3_VALID; - } - - lut_data[6] |= entry.sc_index << 17; - - if ((flags & OSI_LUT_FLAGS_DVLAN_PKT) == OSI_LUT_FLAGS_DVLAN_PKT) { - lut_data[6] |= MACSEC_TX_SCI_LUT_DVLAN_PKT; - } - - if ((flags & OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == - OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { - lut_data[6] |= MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL; - } - return 0; -} - -/** - * @brief sci_lut_config - update hardware registers with Tx/Rx sci lut params - * - * @note - * Algorithm: - * - Return -1 for invalid index - * - Update the Tx/Rx sci lut_data to h/w registers and update the flags to - * h/w registers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used. Used params - * table_config, sci_lut_out - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t sci_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - struct osi_macsec_table_config table_config = lut_config->table_config; - struct osi_sci_lut_outputs entry = lut_config->sci_lut_out; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t val = 0; - nveu32_t index = lut_config->table_config.index; - nve32_t ret = 0; - - if ((entry.sc_index > OSI_SC_INDEX_MAX) || - (lut_config->table_config.index > OSI_SC_LUT_MAX_INDEX)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SCI LUT config err - Invalid Index\n", 0ULL); - return -1; - } - - switch (table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - if (tx_sci_lut_config(lut_config, lut_data) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to config tx sci LUT\n", 0ULL); - return -1; - } - commit_lut_data(osi_core, lut_data); - - if ((lut_config->flags & OSI_LUT_FLAGS_ENTRY_VALID) == - OSI_LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr + - MACSEC_TX_SCI_LUT_VALID); - val |= ((nveu32_t)(1U) << index); - osi_writela(osi_core, val, addr + - MACSEC_TX_SCI_LUT_VALID); - } else { - val = osi_readla(osi_core, addr + - MACSEC_TX_SCI_LUT_VALID); - val &= ~((nveu32_t)(1U) << index); - osi_writela(osi_core, val, addr + - MACSEC_TX_SCI_LUT_VALID); - } - - break; - case OSI_CTLR_SEL_RX: - if (rx_sci_lut_config(lut_config, lut_data) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to config rx sci LUT\n", 0ULL); - return -1; - } - commit_lut_data(osi_core, lut_data); - - if ((lut_config->flags & OSI_LUT_FLAGS_ENTRY_VALID) == - OSI_LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr + - MACSEC_RX_SCI_LUT_VALID); - val |= ((nveu32_t)(1U) << index); - osi_writela(osi_core, val, addr + - MACSEC_RX_SCI_LUT_VALID); - } else { - val = osi_readla(osi_core, addr + - MACSEC_RX_SCI_LUT_VALID); - val &= ~((nveu32_t)(1U) << index); - osi_writela(osi_core, val, addr + - MACSEC_RX_SCI_LUT_VALID); - } - - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller select\n", 0ULL); - ret = -1; - break; - } - return ret; -} - -/** - * @brief byp_lut_config - update hardware registers with Tx/Rx byp lut params - * - * @note - * Algorithm: - * - Update the Tx/Rx bypass lut_data to h/w registers and update the flags to - * h/w registers - * - Update the flags with valid or invalid entries - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used. Used params table_config - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t byp_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nveu32_t lut_data[MACSEC_LUT_DATA_REG_CNT] = {0}; - nveu32_t flags = lut_config->flags; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t val = 0; - nveu32_t index = lut_config->table_config.index; - nve32_t ret = 0; - - if (lut_config_inputs(lut_config, lut_data) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "LUT inputs error\n", 0ULL); - return -1; - } - - /* Lookup output */ - if ((flags & OSI_LUT_FLAGS_CONTROLLED_PORT) == - OSI_LUT_FLAGS_CONTROLLED_PORT) { - lut_data[6] |= MACSEC_LUT_CONTROLLED_PORT; - } - - if ((flags & OSI_LUT_FLAGS_DVLAN_PKT) == OSI_LUT_FLAGS_DVLAN_PKT) { - lut_data[6] |= MACSEC_BYP_LUT_DVLAN_PKT; - } - - if ((flags & OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) == - OSI_LUT_FLAGS_DVLAN_OUTER_INNER_TAG_SEL) { - lut_data[6] |= BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL; - } - - commit_lut_data(osi_core, lut_data); - - switch (lut_config->table_config.ctlr_sel) { - case OSI_CTLR_SEL_TX: - if ((flags & OSI_LUT_FLAGS_ENTRY_VALID) == - OSI_LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr + - MACSEC_TX_BYP_LUT_VALID); - val |= ((nveu32_t)(1U) << (index & 0x1FU)); - osi_writela(osi_core, val, addr + - MACSEC_TX_BYP_LUT_VALID); - } else { - val = osi_readla(osi_core, addr + - MACSEC_TX_BYP_LUT_VALID); - val &= ~((nveu32_t)(1U) << (index & 0x1FU)); - osi_writela(osi_core, val, addr + - MACSEC_TX_BYP_LUT_VALID); - } - break; - - case OSI_CTLR_SEL_RX: - if ((flags & OSI_LUT_FLAGS_ENTRY_VALID) == - OSI_LUT_FLAGS_ENTRY_VALID) { - val = osi_readla(osi_core, addr + - MACSEC_RX_BYP_LUT_VALID); - val |= ((nveu32_t)(1U) << (index & 0x1FU)); - osi_writela(osi_core, val, addr + - MACSEC_RX_BYP_LUT_VALID); - } else { - val = osi_readla(osi_core, addr + - MACSEC_RX_BYP_LUT_VALID); - val &= ~((nveu32_t)(1U) << (index & 0x1FU)); - osi_writela(osi_core, val, addr + - MACSEC_RX_BYP_LUT_VALID); - } - - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unknown controller select\n", 0ULL); - ret = -1; - break; - } - - return ret; -} - -/** - * @brief lut_data_write - update hardware registers with different LUT params - * - * @note - * Algorithm: - * - Update the h/w registers for different LUT types - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] lut_config: attributes from lut_config is used - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static inline nve32_t lut_data_write(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nve32_t ret = 0; - - switch (lut_config->lut_sel) { - case OSI_LUT_SEL_BYPASS: - ret = byp_lut_config(osi_core, lut_config); - break; - case OSI_LUT_SEL_SCI: - ret = sci_lut_config(osi_core, lut_config); - break; - case OSI_LUT_SEL_SC_PARAM: - ret = sc_param_lut_config(osi_core, lut_config); - break; - case OSI_LUT_SEL_SC_STATE: - ret = sc_state_lut_config(osi_core, lut_config); - break; - case OSI_LUT_SEL_SA_STATE: - ret = sa_state_lut_config(osi_core, lut_config); - break; - default: - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Unsupported LUT\n", 0ULL); - ret = -1; - break; - } - - return ret; -} - -/** - * @brief validate_lut_conf - validate the lut_config params - * - * @note - * Algorithm: - * - Return -1 if any of the lut_config attributes are invalid - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] lut_config: attributes from lut_config is used - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t validate_lut_conf(const struct osi_macsec_lut_config *const lut_config) -{ - /* Validate LUT config */ - if ((lut_config->table_config.ctlr_sel > OSI_CTLR_SEL_MAX) || - (lut_config->table_config.rw > OSI_RW_MAX) || - (lut_config->table_config.index > OSI_TABLE_INDEX_MAX) || - (lut_config->lut_sel > OSI_LUT_SEL_MAX)) { - LOG("Validating LUT config failed. ctrl: %hu," - " rw: %hu, index: %hu, lut_sel: %hu", - lut_config->table_config.ctlr_sel, - lut_config->table_config.rw, - lut_config->table_config.index, lut_config->lut_sel); - return -1; - } - return 0; -} - -/** - * @brief macsec_lut_config - update hardware registers with different LUT params - * - * @note - * Algorithm: - * - Validate if params are fine else return -1 - * - Poll for the previous update to be finished - * - Select the controller based on lut_config - * - Update the h/w registers for different LUT types if write attribute is - * passed through lut_config - * - Poll for the h/w confirmation on the lut_update - * - If the lut_config has read attribute read the lut and return -1 on failure - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] lut_config: attributes from lut_config is used. Param used table_config - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_lut_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - nve32_t ret = 0; - nveu32_t lut_config_reg; - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - - if (validate_lut_conf(lut_config) < 0) { - return -1; - } - - /* Wait for previous LUT update to finish */ - ret = poll_for_lut_update(osi_core); - if (ret < 0) { - return ret; - } - - lut_config_reg = osi_readla(osi_core, base + MACSEC_LUT_CONFIG); - if (lut_config->table_config.ctlr_sel != OSI_NONE) { - lut_config_reg |= MACSEC_LUT_CONFIG_CTLR_SEL; - } else { - lut_config_reg &= ~MACSEC_LUT_CONFIG_CTLR_SEL; - } - - if (lut_config->table_config.rw != OSI_NONE) { - lut_config_reg |= MACSEC_LUT_CONFIG_RW; - /* For write operation, load the lut_data registers */ - ret = lut_data_write(osi_core, lut_config); - if (ret < 0) { - return ret; - } - } else { - lut_config_reg &= ~MACSEC_LUT_CONFIG_RW; - } - - lut_config_reg &= ~MACSEC_LUT_CONFIG_LUT_SEL_MASK; - lut_config_reg |= ((nveu32_t)(lut_config->lut_sel) << - MACSEC_LUT_CONFIG_LUT_SEL_SHIFT); - - lut_config_reg &= ~MACSEC_LUT_CONFIG_INDEX_MASK; - lut_config_reg |= (nveu32_t)(lut_config->table_config.index); - - lut_config_reg |= MACSEC_LUT_CONFIG_UPDATE; - osi_writela(osi_core, lut_config_reg, base + MACSEC_LUT_CONFIG); - - /* Wait for this LUT update to finish */ - ret = poll_for_lut_update(osi_core); - if (ret < 0) { - return ret; - } - - if (lut_config->table_config.rw == OSI_NONE) { - ret = lut_data_read(osi_core, lut_config); - if (ret < 0) { - return ret; - } - } - - return 0; -} - -/** - * @brief handle_rx_sc_invalid_key - Handles the Rx sc invalid key interrupt - * - * @note - * Algorithm: - * - Clears MACSEC_RX_SC_KEY_INVALID_STS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_rx_sc_invalid_key( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - LOG("%s()\n", __func__); - - /** check which SC/AN had triggered and clear */ - /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + MACSEC_RX_SC_KEY_INVALID_STS0_0); - osi_writela(osi_core, clear, addr + MACSEC_RX_SC_KEY_INVALID_STS0_0); - /* rx_sc8_15 */ - clear = osi_readla(osi_core, addr + MACSEC_RX_SC_KEY_INVALID_STS1_0); - osi_writela(osi_core, clear, addr + MACSEC_RX_SC_KEY_INVALID_STS1_0); -} - -/** - * @brief handle_tx_sc_invalid_key - Handles the Tx sc invalid key interrupt - * - * @note - * Algorithm: - * - Clears MACSEC_TX_SC_KEY_INVALID_STS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_tx_sc_invalid_key( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - LOG("%s()\n", __func__); - - /** check which SC/AN had triggered and clear */ - /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + MACSEC_TX_SC_KEY_INVALID_STS0_0); - osi_writela(osi_core, clear, addr + MACSEC_TX_SC_KEY_INVALID_STS0_0); - /* tx_sc8_15 */ - clear = osi_readla(osi_core, addr + MACSEC_TX_SC_KEY_INVALID_STS1_0); - osi_writela(osi_core, clear, addr + MACSEC_TX_SC_KEY_INVALID_STS1_0); -} - -/** - * @brief handle_safety_err_irq - Safety Error handler - * - * @note - * Algorithm: - * - Nothing is handled - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_safety_err_irq( - const struct osi_core_priv_data *const osi_core) -{ - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Safety Error Handler \n", 0ULL); - LOG("%s()\n", __func__); -} - -/** - * @brief handle_rx_sc_replay_err - Rx SC replay error handler - * - * @note - * Algorithm: - * - Clears MACSEC_RX_SC_REPLAY_ERROR_STATUS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_rx_sc_replay_err( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + - MACSEC_RX_SC_REPLAY_ERROR_STATUS0_0); - osi_writela(osi_core, clear, addr + - MACSEC_RX_SC_REPLAY_ERROR_STATUS0_0); - /* rx_sc8_15 */ - clear = osi_readla(osi_core, addr + - MACSEC_RX_SC_REPLAY_ERROR_STATUS1_0); - osi_writela(osi_core, clear, addr + - MACSEC_RX_SC_REPLAY_ERROR_STATUS1_0); -} - -/** - * @brief handle_rx_pn_exhausted - Rx PN exhaustion handler - * - * @note - * Algorithm: - * - Clears MACSEC_RX_SC_PN_EXHAUSTED_STATUS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_rx_pn_exhausted( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - /* Check which SC/AN had triggered and clear */ - /* rx_sc0_7 */ - clear = osi_readla(osi_core, addr + - MACSEC_RX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writela(osi_core, clear, addr + - MACSEC_RX_SC_PN_EXHAUSTED_STATUS0_0); - /* rx_sc8_15 */ - clear = osi_readla(osi_core, addr + - MACSEC_RX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writela(osi_core, clear, addr + - MACSEC_RX_SC_PN_EXHAUSTED_STATUS1_0); -} - -/** - * @brief handle_tx_sc_err - Tx SC error handler - * - * @note - * Algorithm: - * - Clears MACSEC_TX_SC_ERROR_INTERRUPT_STATUS_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_tx_sc_err(struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - clear = osi_readla(osi_core, addr + - MACSEC_TX_SC_ERROR_INTERRUPT_STATUS_0); - osi_writela(osi_core, clear, addr + - MACSEC_TX_SC_ERROR_INTERRUPT_STATUS_0); - -} - -/** - * @brief handle_tx_pn_threshold - Tx PN Threshold handler - * - * @note - * Algorithm: - * - Clears MACSEC_TX_SC_PN_THRESHOLD_STATUS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_tx_pn_threshold( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - /* check which SC/AN had triggered and clear */ - /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + - MACSEC_TX_SC_PN_THRESHOLD_STATUS0_0); - osi_writela(osi_core, clear, addr + - MACSEC_TX_SC_PN_THRESHOLD_STATUS0_0); - /* tx_sc8_15 */ - clear = osi_readla(osi_core, addr + - MACSEC_TX_SC_PN_THRESHOLD_STATUS1_0); - osi_writela(osi_core, clear, addr + - MACSEC_TX_SC_PN_THRESHOLD_STATUS1_0); -} - -/** - * @brief handle_tx_pn_exhausted - Tx PN exhaustion handler - * - * @note - * Algorithm: - * - Clears MACSEC_TX_SC_PN_EXHAUSTED_STATUS0_0 status register - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_tx_pn_exhausted( - struct osi_core_priv_data *const osi_core) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t clear = 0; - - /* check which SC/AN had triggered and clear */ - /* tx_sc0_7 */ - clear = osi_readla(osi_core, addr + - MACSEC_TX_SC_PN_EXHAUSTED_STATUS0_0); - osi_writela(osi_core, clear, addr + - MACSEC_TX_SC_PN_EXHAUSTED_STATUS0_0); - /* tx_sc8_15 */ - clear = osi_readla(osi_core, addr + - MACSEC_TX_SC_PN_EXHAUSTED_STATUS1_0); - osi_writela(osi_core, clear, addr + - MACSEC_TX_SC_PN_EXHAUSTED_STATUS1_0); -} - -/** - * @brief handle_dbg_evt_capture_done - Debug event handler - * - * @note - * Algorithm: - * - Clears the Tx/Rx debug status register - * - Disabled the trigger events - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] ctrl_sel: Controller selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_dbg_evt_capture_done( - struct osi_core_priv_data *const osi_core, - nveu16_t ctrl_sel) -{ - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nveu32_t trigger_evts = 0; - - if (ctrl_sel == OSI_CTLR_SEL_TX) { - trigger_evts = osi_readla(osi_core, addr + - MACSEC_TX_DEBUG_STATUS_0); - osi_writela(osi_core, trigger_evts, addr + - MACSEC_TX_DEBUG_STATUS_0); - /* clear all trigger events */ - trigger_evts = 0U; - osi_writela(osi_core, trigger_evts, - addr + MACSEC_TX_DEBUG_TRIGGER_EN_0); - } else if (ctrl_sel == OSI_CTLR_SEL_RX) { - trigger_evts = osi_readla(osi_core, addr + - MACSEC_RX_DEBUG_STATUS_0); - osi_writela(osi_core, trigger_evts, addr + - MACSEC_RX_DEBUG_STATUS_0); - /* clear all trigger events */ - trigger_evts = 0U; - osi_writela(osi_core, trigger_evts, - addr + MACSEC_RX_DEBUG_TRIGGER_EN_0); - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalid ctrl selected\n", 0ULL); - } -} - -/** - * @brief handle_tx_irq - Handles all Tx interrupts - * - * @note - * Algorithm: - * - Clears the Below Interrupt status - * - Tx DBG buffer capture done - * - Tx MTU check fail - * - Tx AES GCM overflow - * - Tx SC AN Not valid - * - Tx MAC CRC Error - * - If HSi is enabled and threshold is met, hsi report counters - * are incremented - * - Tx PN Threshold reached - * - Tx PN Exhausted - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_tx_irq(struct osi_core_priv_data *const osi_core) -{ - nveu32_t tx_isr, clear = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; -#ifdef HSI_SUPPORT - nveu64_t tx_crc_err = 0; -#endif - - tx_isr = osi_readla(osi_core, addr + MACSEC_TX_ISR); - LOG("%s(): tx_isr 0x%x\n", __func__, tx_isr); - if ((tx_isr & MACSEC_TX_DBG_BUF_CAPTURE_DONE) == - MACSEC_TX_DBG_BUF_CAPTURE_DONE) { - handle_dbg_evt_capture_done(osi_core, OSI_CTLR_SEL_TX); - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_dbg_capture_done); - clear |= MACSEC_TX_DBG_BUF_CAPTURE_DONE; - } - - if ((tx_isr & MACSEC_TX_MTU_CHECK_FAIL) == MACSEC_TX_MTU_CHECK_FAIL) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_mtu_check_fail); - clear |= MACSEC_TX_MTU_CHECK_FAIL; - } - - if ((tx_isr & MACSEC_TX_AES_GCM_BUF_OVF) == MACSEC_TX_AES_GCM_BUF_OVF) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_aes_gcm_buf_ovf); - clear |= MACSEC_TX_AES_GCM_BUF_OVF; - } - - if ((tx_isr & MACSEC_TX_SC_AN_NOT_VALID) == MACSEC_TX_SC_AN_NOT_VALID) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_sc_an_not_valid); - handle_tx_sc_err(osi_core); - clear |= MACSEC_TX_SC_AN_NOT_VALID; - } - - if ((tx_isr & MACSEC_TX_MAC_CRC_ERROR) == MACSEC_TX_MAC_CRC_ERROR) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_mac_crc_error); - clear |= MACSEC_TX_MAC_CRC_ERROR; -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - tx_crc_err = osi_core->macsec_irq_stats.tx_mac_crc_error / - osi_core->hsi.err_count_threshold; - if (osi_core->hsi.macsec_tx_crc_err_count < tx_crc_err) { - osi_core->hsi.macsec_tx_crc_err_count = tx_crc_err; - osi_core->hsi.macsec_report_count_err[MACSEC_TX_CRC_ERR_IDX] = - OSI_ENABLE; - } - - osi_core->hsi.macsec_err_code[MACSEC_TX_CRC_ERR_IDX] = - OSI_MACSEC_TX_CRC_ERR; - osi_core->hsi.macsec_report_err = OSI_ENABLE; - } -#endif - } - - if ((tx_isr & MACSEC_TX_PN_THRSHLD_RCHD) == MACSEC_TX_PN_THRSHLD_RCHD) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_pn_threshold); - handle_tx_pn_threshold(osi_core); - clear |= MACSEC_TX_PN_THRSHLD_RCHD; - } - - if ((tx_isr & MACSEC_TX_PN_EXHAUSTED) == MACSEC_TX_PN_EXHAUSTED) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_pn_exhausted); - handle_tx_pn_exhausted(osi_core); - clear |= MACSEC_TX_PN_EXHAUSTED; - } - if (clear != OSI_NONE) { - osi_writela(osi_core, clear, addr + MACSEC_TX_ISR); - } -} - -/** - * @brief handle_rx_irq - Handles all Rx interrupts - * - * @note - * Algorithm: - * - Clears the Below Interrupt status - * - Rx DBG buffer capture done - * - Rx ICV check fail - * - If HSi is enabled and threshold is met, hsi report counters - * are incremented - * - Rx Replay error - * - Rx MTU check fail - * - Rx AES GCM overflow - * - Rx MAC CRC check failed - * - If HSi is enabled and threshold is met, hsi report counters - * are incremented - * - Rx PN Exhausted - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_rx_irq(struct osi_core_priv_data *const osi_core) -{ - nveu32_t rx_isr, clear = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; -#ifdef HSI_SUPPORT - nveu64_t rx_crc_err = 0; - nveu64_t rx_icv_err = 0; -#endif - - rx_isr = osi_readla(osi_core, addr + MACSEC_RX_ISR); - LOG("%s(): rx_isr 0x%x\n", __func__, rx_isr); - - if ((rx_isr & MACSEC_RX_DBG_BUF_CAPTURE_DONE) == - MACSEC_RX_DBG_BUF_CAPTURE_DONE) { - handle_dbg_evt_capture_done(osi_core, OSI_CTLR_SEL_RX); - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_dbg_capture_done); - clear |= MACSEC_RX_DBG_BUF_CAPTURE_DONE; - } - - if ((rx_isr & MACSEC_RX_ICV_ERROR) == MACSEC_RX_ICV_ERROR) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_icv_err_threshold); - clear |= MACSEC_RX_ICV_ERROR; -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - rx_icv_err = osi_core->macsec_irq_stats.rx_icv_err_threshold / - osi_core->hsi.err_count_threshold; - if (osi_core->hsi.macsec_rx_icv_err_count < rx_icv_err) { - osi_core->hsi.macsec_rx_icv_err_count = rx_icv_err; - osi_core->hsi.macsec_report_count_err[MACSEC_RX_ICV_ERR_IDX] = - OSI_ENABLE; - } - osi_core->hsi.macsec_err_code[MACSEC_RX_ICV_ERR_IDX] = - OSI_MACSEC_RX_ICV_ERR; - osi_core->hsi.macsec_report_err = OSI_ENABLE; - } -#endif - } - - if ((rx_isr & MACSEC_RX_REPLAY_ERROR) == MACSEC_RX_REPLAY_ERROR) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_replay_error); - handle_rx_sc_replay_err(osi_core); - clear |= MACSEC_RX_REPLAY_ERROR; - } - - if ((rx_isr & MACSEC_RX_MTU_CHECK_FAIL) == MACSEC_RX_MTU_CHECK_FAIL) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_mtu_check_fail); - clear |= MACSEC_RX_MTU_CHECK_FAIL; - } - - if ((rx_isr & MACSEC_RX_AES_GCM_BUF_OVF) == MACSEC_RX_AES_GCM_BUF_OVF) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_aes_gcm_buf_ovf); - clear |= MACSEC_RX_AES_GCM_BUF_OVF; - } - - if ((rx_isr & MACSEC_RX_MAC_CRC_ERROR) == MACSEC_RX_MAC_CRC_ERROR) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_mac_crc_error); - clear |= MACSEC_RX_MAC_CRC_ERROR; -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - rx_crc_err = osi_core->macsec_irq_stats.rx_mac_crc_error / - osi_core->hsi.err_count_threshold; - if (osi_core->hsi.macsec_rx_crc_err_count < rx_crc_err) { - osi_core->hsi.macsec_rx_crc_err_count = rx_crc_err; - osi_core->hsi.macsec_report_count_err[MACSEC_RX_CRC_ERR_IDX] = - OSI_ENABLE; - } - osi_core->hsi.macsec_err_code[MACSEC_RX_CRC_ERR_IDX] = - OSI_MACSEC_RX_CRC_ERR; - osi_core->hsi.macsec_report_err = OSI_ENABLE; - } -#endif - } - - if ((rx_isr & MACSEC_RX_PN_EXHAUSTED) == MACSEC_RX_PN_EXHAUSTED) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_pn_exhausted); - handle_rx_pn_exhausted(osi_core); - clear |= MACSEC_RX_PN_EXHAUSTED; - } - if (clear != OSI_NONE) { - osi_writela(osi_core, clear, addr + MACSEC_RX_ISR); - } -} - -/** - * @brief handle_common_irq - Common interrupt handler - * - * @note - * Algorithm: - * - Clears the Below Interrupt status - * - Secure register access violation - * - Rx Uninititalized key slot error - * - Rx Lookup miss event - * - Tx Uninititalized key slot error - * - Tx Lookup miss event - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void handle_common_irq(struct osi_core_priv_data *const osi_core) -{ - nveu32_t common_isr, clear = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - - common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); - LOG("%s(): common_isr 0x%x\n", __func__, common_isr); - - if ((common_isr & MACSEC_SECURE_REG_VIOL) == MACSEC_SECURE_REG_VIOL) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.secure_reg_viol); - clear |= MACSEC_SECURE_REG_VIOL; - } - - if ((common_isr & MACSEC_RX_UNINIT_KEY_SLOT) == - MACSEC_RX_UNINIT_KEY_SLOT) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_uninit_key_slot); - clear |= MACSEC_RX_UNINIT_KEY_SLOT; - handle_rx_sc_invalid_key(osi_core); - } - - if ((common_isr & MACSEC_RX_LKUP_MISS) == MACSEC_RX_LKUP_MISS) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.rx_lkup_miss); - clear |= MACSEC_RX_LKUP_MISS; - } - - if ((common_isr & MACSEC_TX_UNINIT_KEY_SLOT) == - MACSEC_TX_UNINIT_KEY_SLOT) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_uninit_key_slot); - clear |= MACSEC_TX_UNINIT_KEY_SLOT; - handle_tx_sc_invalid_key(osi_core); - } - - if ((common_isr & MACSEC_TX_LKUP_MISS) == MACSEC_TX_LKUP_MISS) { - CERT_C__POST_INC__U64(osi_core->macsec_irq_stats.tx_lkup_miss); - clear |= MACSEC_TX_LKUP_MISS; - } - if (clear != OSI_NONE) { - osi_writela(osi_core, clear, addr + MACSEC_COMMON_ISR); - } -} - -/** - * @brief macsec_handle_ns_irq - Non-secure interrupt handler - * - * @note - * Algorithm: - * - Handles below non-secure interrupts - * - Handles Tx interrupts - * - Handles Rx interrupts - * - Handles Safety interrupts - * - Handles common interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void macsec_handle_ns_irq(struct osi_core_priv_data *const osi_core) -{ - nveu32_t irq_common_sr, common_isr; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - - irq_common_sr = osi_readla(osi_core, addr + MACSEC_INTERRUPT_COMMON_SR); - LOG("%s(): common_sr 0x%x\n", __func__, irq_common_sr); - if ((irq_common_sr & MACSEC_COMMON_SR_TX) == MACSEC_COMMON_SR_TX) { - handle_tx_irq(osi_core); - } - - if ((irq_common_sr & MACSEC_COMMON_SR_RX) == MACSEC_COMMON_SR_RX) { - handle_rx_irq(osi_core); - } - - if ((irq_common_sr & MACSEC_COMMON_SR_SFTY_ERR) == - MACSEC_COMMON_SR_SFTY_ERR) { - handle_safety_err_irq(osi_core); - } - - common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); - if (common_isr != OSI_NONE) { - handle_common_irq(osi_core); - } -} - -/** - * @brief macsec_handle_s_irq - secure interrupt handler - * - * @note - * Algorithm: - * - Handles common interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void macsec_handle_s_irq(struct osi_core_priv_data *const osi_core) -{ - nveu32_t common_isr; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - - LOG("%s()\n", __func__); - - common_isr = osi_readla(osi_core, addr + MACSEC_COMMON_ISR); - if (common_isr != OSI_NONE) { - handle_common_irq(osi_core); - } -} - -/** - * @brief macsec_cipher_config - Configures the cipher type - * - * @note - * Algorithm: - * - Configures the AES type to h/w registers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] cipher: Cipher type - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t macsec_cipher_config(struct osi_core_priv_data *const osi_core, - nveu32_t cipher) -{ - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t val; - - val = osi_readla(osi_core, base + MACSEC_GCM_AES_CONTROL_0); - - val &= ~MACSEC_TX_AES_MODE_MASK; - val &= ~MACSEC_RX_AES_MODE_MASK; - if (cipher == OSI_MACSEC_CIPHER_AES128) { - val |= MACSEC_TX_AES_MODE_AES128; - val |= MACSEC_RX_AES_MODE_AES128; - } else if (cipher == OSI_MACSEC_CIPHER_AES256) { - val |= MACSEC_TX_AES_MODE_AES256; - val |= MACSEC_RX_AES_MODE_AES256; - } else { - return -1; - } - - osi_writela(osi_core, val, base + MACSEC_GCM_AES_CONTROL_0); - return 0; -} - -/** - * @brief macsec_loopback_config - Configures the loopback mode - * - * @note - * Algorithm: - * - Configures the loopback mode to h/w registers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] enable: Enable or disable the loopback - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t macsec_loopback_config( - struct osi_core_priv_data *const osi_core, - nveu32_t enable) -{ - nveu8_t *base = (nveu8_t *)osi_core->macsec_base; - nveu32_t val; - - val = osi_readla(osi_core, base + MACSEC_CONTROL1); - - if (enable == OSI_ENABLE) { - val |= MACSEC_LOOPBACK_MODE_EN; - } else if (enable == OSI_DISABLE) { - val &= ~MACSEC_LOOPBACK_MODE_EN; - } else { - return -1; - } - - osi_writela(osi_core, val, base + MACSEC_CONTROL1); - return 0; -} - -/** - * @brief clear_byp_lut - Clears the bypass lut - * - * @note - * Algorithm: - * - Clears the bypass lut for all the indices in both Tx and Rx controllers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_byp_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu16_t i, j; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Tx/Rx BYP LUT */ - lut_config.lut_sel = OSI_LUT_SEL_BYPASS; - for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { - table_config->ctlr_sel = i; - for (j = 0; j <= OSI_BYP_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing CTLR:BYPASS LUT:INDEX: \n", j); - return ret; - } - } - } - - return ret; -} - -/** - * @brief clear_sci_lut - Clears the sci lut - * - * @note - * Algorithm: - * - Clears the sci lut for all the indices in both Tx and Rx controllers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_sci_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu16_t i, j; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Tx/Rx SCI LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SCI; - for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { - table_config->ctlr_sel = i; - for (j = 0; j <= OSI_SC_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing CTLR:SCI LUT:INDEX: \n", j); - return ret; - } - } - } - return ret; -} - -/** - * @brief clear_sc_param_lut - Clears the sc param lut - * - * @note - * Algorithm: - * - Clears the sc param lut for all the indices in both Tx and Rx controllers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_sc_param_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu16_t i, j; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Tx/Rx SC param LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; - for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { - table_config->ctlr_sel = i; - for (j = 0; j <= OSI_SC_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing CTLR:SC PARAM LUT:INDEX: \n", j); - return ret; - } - } - } - return ret; - -} - -/** - * @brief clear_sc_state_lut - Clears the sc state lut - * - * @note - * Algorithm: - * - Clears the sc state lut for all the indices in both Tx and Rx controllers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_sc_state_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu16_t i, j; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Tx/Rx SC state */ - lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { - table_config->ctlr_sel = i; - for (j = 0; j <= OSI_SC_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing CTLR:SC STATE LUT:INDEX: \n", j); - return ret; - } - } - } - return ret; - -} - -/** - * @brief clear_sa_state_lut - Clears the sa state lut - * - * @note - * Algorithm: - * - Clears the sa state lut for all the indices in both Tx and Rx controllers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_sa_state_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nveu16_t j; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Tx SA state LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->ctlr_sel = OSI_CTLR_SEL_TX; - for (j = 0; j <= OSI_SA_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing TX CTLR:SA STATE LUT:INDEX: \n", j); - return ret; - } - } - - /* Rx SA state LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->ctlr_sel = OSI_CTLR_SEL_RX; - for (j = 0; j <= OSI_SA_LUT_MAX_INDEX; j++) { - table_config->index = j; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing RX CTLR:SA STATE LUT:INDEX: \n", j); - return ret; - } - } - return ret; -} - -/** - * @brief clear_lut - Clears all the LUTs - * - * @note - * Algorithm: - * - Clears all of the below LUTs - * - SCI LUT - * - SC param LUT - * - SC state LUT - * - SA state LUT - * - key for all the SAs - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t clear_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; -#ifdef MACSEC_KEY_PROGRAM - struct osi_macsec_kt_config kt_config = {0}; - nveu16_t i, j; -#endif - struct osi_macsec_table_config *table_config = &lut_config.table_config; - nve32_t ret = 0; - - table_config->rw = OSI_LUT_WRITE; - /* Clear all the LUT's which have a dedicated LUT valid bit per entry */ - ret = clear_byp_lut(osi_core); - if (ret < 0) { - return ret; - } - ret = clear_sci_lut(osi_core); - if (ret < 0) { - return ret; - } - ret = clear_sc_param_lut(osi_core); - if (ret < 0) { - return ret; - } - ret = clear_sc_state_lut(osi_core); - if (ret < 0) { - return ret; - } - ret = clear_sa_state_lut(osi_core); - if (ret < 0) { - return ret; - } - -#ifdef MACSEC_KEY_PROGRAM - /* Key table */ - table_config = &kt_config.table_config; - table_config->rw = OSI_LUT_WRITE; - for (i = 0; i <= OSI_CTLR_SEL_MAX; i++) { - table_config->ctlr_sel = i; - for (j = 0; j <= OSI_TABLE_INDEX_MAX; j++) { - table_config->index = j; - ret = macsec_kt_config(osi_core, &kt_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Error clearing KT LUT:INDEX: \n", j); - return ret; - } - } - } -#endif /* MACSEC_KEY_PROGRAM */ - - return ret; -} - -/** - * @brief macsec_deinit - Deinitializes the macsec - * - * @note - * Algorithm: - * - Clears the lut_status buffer - * - Programs the mac IPG and MTL_EST values with MACSEC disabled set of values - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 - */ -static nve32_t macsec_deinit(struct osi_core_priv_data *const osi_core) -{ - nveu32_t i; - const struct core_local *l_core = (void *)osi_core; - - for (i = OSI_CTLR_SEL_TX; i <= OSI_CTLR_SEL_RX; i++) { - osi_memset(&osi_core->macsec_lut_status[i], OSI_NONE, - sizeof(struct osi_macsec_lut_status)); - } - - /* Update MAC as per macsec requirement */ - if (l_core->ops_p->macsec_config_mac != OSI_NULL) { - l_core->ops_p->macsec_config_mac(osi_core, OSI_DISABLE); - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed config MAC per macsec\n", 0ULL); - } - return 0; -} - -/** - * @brief macsec_update_mtu - Updates macsec MTU - * - * @note - * Algorithm: - * - Returns if invalid mtu received - * - Programs the tx and rx MTU to macsec h/w registers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] mtu: mtu to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t macsec_update_mtu(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - nveu32_t val = 0; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - - if (mtu > OSI_MAX_MTU_SIZE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalid MTU received!!\n", mtu); - return -1; - } - /* Set MTU */ - val = osi_readla(osi_core, addr + MACSEC_TX_MTU_LEN); - LOG("Read MACSEC_TX_MTU_LEN: 0x%x\n", val); - val &= ~(MTU_LENGTH_MASK); - val |= (mtu & MTU_LENGTH_MASK); - LOG("Write MACSEC_TX_MTU_LEN: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_TX_MTU_LEN); - - val = osi_readla(osi_core, addr + MACSEC_RX_MTU_LEN); - LOG("Read MACSEC_RX_MTU_LEN: 0x%x\n", val); - val &= ~(MTU_LENGTH_MASK); - val |= (mtu & MTU_LENGTH_MASK); - LOG("Write MACSEC_RX_MTU_LEN: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_RX_MTU_LEN); - - return 0; -} - -/** - * @brief set_byp_lut - Sets bypass lut - * - * @note - * Algorithm: - * - Adds broadcast address to the Tx and Rx Bypass luts - * - Adds the mkpdu multi case address to the Tx and Rx Bypass luts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t set_byp_lut(struct osi_core_priv_data *const osi_core) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config = &lut_config.table_config; - /* Store MAC address in reverse, per HW design */ - const nveu8_t mac_da_mkpdu[OSI_ETH_ALEN] = {0x3, 0x0, 0x0, - 0xC2, 0x80, 0x01}; - const nveu8_t mac_da_bc[OSI_ETH_ALEN] = {0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF}; - nve32_t ret = 0; - nveu16_t i, j; - - /* Set default BYP for MKPDU/BC packets */ - table_config->rw = OSI_LUT_WRITE; - lut_config.lut_sel = OSI_LUT_SEL_BYPASS; - lut_config.flags |= (OSI_LUT_FLAGS_DA_VALID | - OSI_LUT_FLAGS_ENTRY_VALID); - for (j = 0; j < OSI_ETH_ALEN; j++) { - lut_config.lut_in.da[j] = mac_da_bc[j]; - } - - for (i = OSI_CTLR_SEL_TX; i <= OSI_CTLR_SEL_RX; i++) { - table_config->ctlr_sel = i; - table_config->index = - osi_core->macsec_lut_status[i].next_byp_idx; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set BYP for BC addr\n", (nveul64_t)ret); - return ret; - } else { - osi_core->macsec_lut_status[i].next_byp_idx = - ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); - } - } - - for (j = 0; j < OSI_ETH_ALEN; j++) { - lut_config.lut_in.da[j] = mac_da_mkpdu[j]; - } - - for (i = OSI_CTLR_SEL_TX; i <= OSI_CTLR_SEL_RX; i++) { - table_config->ctlr_sel = i; - table_config->index = - osi_core->macsec_lut_status[i].next_byp_idx; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set BYP for MKPDU multicast DA\n", (nveul64_t)ret); - - return ret; - } else { - osi_core->macsec_lut_status[i].next_byp_idx = - ((osi_core->macsec_lut_status[i].next_byp_idx & 0xFFU) + 1U); - } - } - return 0; -} - -/** - * @brief macsec_init - Inititlizes macsec - * - * @note - * Algorithm: - * - Configures mac IPG and MTL_EST with MACSEC enabled values - * - Sets the macsec MTU - * - If the mac type is eqos sets the Start of Transmission delays - * - Enables below interrupts - * - Tx/Rx Lookup miss - * - Validate frames to strict - * - Rx replay protection enable - * - Tx/Rx MTU check enable - * - Tx LUT priority to bypass lut - * - Enable Stats roll-over - * - Enables Tx interrupts - * - Enables Rx interrupts - * - Enables common interrupts - * - Clears all the luts, return -1 on failure - * - Sets the bypass lut, return -1 on failure - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] mtu: mtu to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 for success - * @retval -1 for failure - */ -static nve32_t macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - nveu32_t val = 0; - const struct core_local *l_core = (void *)osi_core; - nveu8_t *addr = (nveu8_t *)osi_core->macsec_base; - nve32_t ret = 0; - - /* Update MAC value as per macsec requirement */ - if (l_core->ops_p->macsec_config_mac != OSI_NULL) { - l_core->ops_p->macsec_config_mac(osi_core, OSI_ENABLE); - } else { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to config mac per macsec\n", 0ULL); - } - - /* Set MTU */ - ret = macsec_update_mtu(osi_core, mtu); - if (ret < 0) { - return ret; - } - - /* set TX/RX SOT, as SOT value different for eqos. - * default value matches for MGBE - */ - if (osi_core->mac == OSI_MAC_HW_EQOS) { - val = osi_readla(osi_core, addr + MACSEC_TX_SOT_DELAY); - LOG("Read MACSEC_TX_SOT_DELAY: 0x%x\n", val); - val &= ~(SOT_LENGTH_MASK); - val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - LOG("Write MACSEC_TX_SOT_DELAY: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_TX_SOT_DELAY); - - val = osi_readla(osi_core, addr + MACSEC_RX_SOT_DELAY); - LOG("Read MACSEC_RX_SOT_DELAY: 0x%x\n", val); - val &= ~(SOT_LENGTH_MASK); - val |= (EQOS_MACSEC_SOT_DELAY & SOT_LENGTH_MASK); - LOG("Write MACSEC_RX_SOT_DELAY: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_RX_SOT_DELAY); - } - - /* Set essential MACsec control configuration */ - val = osi_readla(osi_core, addr + MACSEC_CONTROL0); - LOG("Read MACSEC_CONTROL0: 0x%x\n", val); - val |= (MACSEC_TX_LKUP_MISS_NS_INTR | MACSEC_RX_LKUP_MISS_NS_INTR | - MACSEC_TX_LKUP_MISS_BYPASS | MACSEC_RX_LKUP_MISS_BYPASS); - val &= ~(MACSEC_VALIDATE_FRAMES_MASK); - val |= MACSEC_VALIDATE_FRAMES_STRICT; - val |= MACSEC_RX_REPLAY_PROT_EN; - LOG("Write MACSEC_CONTROL0: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_CONTROL0); - - val = osi_readla(osi_core, addr + MACSEC_CONTROL1); - LOG("Read MACSEC_CONTROL1: 0x%x\n", val); - val |= (MACSEC_RX_MTU_CHECK_EN | MACSEC_TX_LUT_PRIO_BYP | - MACSEC_TX_MTU_CHECK_EN); - LOG("Write MACSEC_CONTROL1: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_CONTROL1); - - val = osi_readla(osi_core, addr + MACSEC_STATS_CONTROL_0); - LOG("Read MACSEC_STATS_CONTROL_0: 0x%x\n", val); - /* set STATS rollover bit */ - val |= MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY; - LOG("Write MACSEC_STATS_CONTROL_0: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_STATS_CONTROL_0); - - /* Enable default interrupts needed */ - val = osi_readla(osi_core, addr + MACSEC_TX_IMR); - LOG("Read MACSEC_TX_IMR: 0x%x\n", val); - val |= (MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN | - MACSEC_TX_MTU_CHECK_FAIL_INT_EN | - MACSEC_TX_MAC_CRC_ERROR_INT_EN | - MACSEC_TX_SC_AN_NOT_VALID_INT_EN | - MACSEC_TX_AES_GCM_BUF_OVF_INT_EN | - MACSEC_TX_PN_EXHAUSTED_INT_EN | - MACSEC_TX_PN_THRSHLD_RCHD_INT_EN); - LOG("Write MACSEC_TX_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_TX_IMR); - - /* set ICV error threshold to 1 */ - osi_writela(osi_core, 1U, addr + MACSEC_RX_ICV_ERR_CNTRL); - - val = osi_readla(osi_core, addr + MACSEC_RX_IMR); - LOG("Read MACSEC_RX_IMR: 0x%x\n", val); - - val |= (MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN | - MACSEC_RX_ICV_ERROR_INT_EN | RX_REPLAY_ERROR_INT_EN | - MACSEC_RX_MTU_CHECK_FAIL_INT_EN | - MACSEC_RX_MAC_CRC_ERROR_INT_EN | - MACSEC_RX_AES_GCM_BUF_OVF_INT_EN | - MACSEC_RX_PN_EXHAUSTED_INT_EN - ); - LOG("Write MACSEC_RX_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_RX_IMR); - - val = osi_readla(osi_core, addr + MACSEC_COMMON_IMR); - LOG("Read MACSEC_COMMON_IMR: 0x%x\n", val); - - val |= (MACSEC_SECURE_REG_VIOL_INT_EN | - MACSEC_RX_UNINIT_KEY_SLOT_INT_EN | - MACSEC_RX_LKUP_MISS_INT_EN | - MACSEC_TX_UNINIT_KEY_SLOT_INT_EN | - MACSEC_TX_LKUP_MISS_INT_EN); - LOG("Write MACSEC_COMMON_IMR: 0x%x\n", val); - osi_writela(osi_core, val, addr + MACSEC_COMMON_IMR); - - /* Set AES mode - * Default power on reset is AES-GCM128, leave it. - */ - - /* Invalidate LUT entries */ - ret = clear_lut(osi_core); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Invalidating all LUT's failed\n", (nveul64_t)ret); - return ret; - } - return set_byp_lut(osi_core); -} - -/** - * @brief find_existing_sc - Find the existing sc - * - * @note - * Algorithm: - * - Compare the received sci with the existing sci and return sc if found - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] sc: Pointer to the sc which needs to be found - * @param[in] ctlr: Controller to be selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval Pointer to sc on success - * @retval NULL on failure - */ -static struct osi_macsec_sc_info *find_existing_sc( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu16_t ctlr) -{ - struct osi_macsec_lut_status *lut_status_ptr = - &osi_core->macsec_lut_status[ctlr]; - nveu32_t i; - - for (i = 0; i < OSI_MAX_NUM_SC; i++) { - if (osi_memcmp(lut_status_ptr->sc_info[i].sci, sc->sci, - (nve32_t)OSI_SCI_LEN) == OSI_NONE_SIGNED) { - return &lut_status_ptr->sc_info[i]; - } - } - - return OSI_NULL; -} - -/** - * @brief get_avail_sc_idx - Find the available SC Index - * - * @note - * Algorithm: - * - Return Index of the SC where valid an is 0 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] ctlr: Controller to be selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval index of the free sc - */ -static nveu32_t get_avail_sc_idx(const struct osi_core_priv_data *const osi_core, - nveu16_t ctlr) -{ - const struct osi_macsec_lut_status *lut_status_ptr = - &osi_core->macsec_lut_status[ctlr]; - nveu32_t i; - - for (i = 0; i < OSI_MAX_NUM_SC; i++) { - if (lut_status_ptr->sc_info[i].an_valid == OSI_NONE) { - return i; - } - } - return i; -} - -/** - * @brief macsec_get_key_index - gets the key index for given sci - * - * @note - * Algorithm: - * - Return -1 for invalid input arguments - * - Find the existing SC for a given sci - * - Derive the key index for the SC found - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] sci: Pointer of sci that needds to be found - * @param[out] key_index: Pointer to the key index to be filled once SCI is found - * @param[in] ctlr: Controller to be selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_get_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nveu32_t *key_index, nveu16_t ctlr) -{ - struct osi_macsec_sc_info sc; - const struct osi_macsec_sc_info *sc_info = OSI_NULL; - nve32_t ret = 0; - - /* Validate inputs */ - if ((sci == OSI_NULL) || (key_index == OSI_NULL) || - (ctlr > OSI_CTLR_SEL_MAX)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Params validation failed\n", 0ULL); - return -1; - } - - ret = osi_memcpy(sc.sci, sci, OSI_SCI_LEN); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy failed\n", 0ULL); - return -1; - } - sc_info = find_existing_sc(osi_core, &sc, ctlr); - if (sc_info == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "SCI Not found\n", 0ULL); - return -1; - } - - *key_index = (sc_info->sc_idx_start * OSI_MAX_NUM_SA); - return 0; -} - -/** - * @brief del_upd_sc - deletes or updates SC - * - * @note - * Algorithm: - * - If the current SA of existing SC is same as passed SA - * - Clear the SCI LUT for the given SC - * - Clear the SC param LUT for the given SC - * - Clear the SC State LUT for the gien SC - * - Clear SA State LUT for the given SC - * - If key programming is enabled clear the key LUT for the given SC - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] existing_sc: Pointer to the existing sc - * @param[in] sc: Pointer to the sc which need to be deleted or updated - * @param[in] ctlr: Controller to be selected - * @param[out] kt_idx: Key index to be passed to osd - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t del_upd_sc(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *existing_sc, - const struct osi_macsec_sc_info *const sc, - nveu16_t ctlr, nveu16_t *kt_idx) -{ -#ifdef MACSEC_KEY_PROGRAM - struct osi_macsec_kt_config kt_config = {0}; -#endif /* MACSEC_KEY_PROGRAM */ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config; - nve32_t ret; - - /* All input/output fields are already zero'd in declaration. - * Write all 0's to LUT index to clear everything - */ - table_config = &lut_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - - /* If curr_an of existing SC is same as AN being deleted, then remove - * SCI LUT entry as well. If not, it means some other AN is already - * enabled, so leave the SC configuration as is. - */ - if (existing_sc->curr_an == sc->curr_an) { - /* 1. SCI LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SCI; - table_config->index = (nveu16_t)(existing_sc->sc_idx_start); - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to del SCI LUT idx\n", - sc->sc_idx_start); - return -1; - } - - /* 2. SC Param LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to del SC param\n", (nveul64_t)ret); - return -1; - } - - /* 3. SC state LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to del SC state\n", (nveul64_t)ret); - return -1; - } - } - - /* 4. SA State LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (nveu16_t)((existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + - sc->curr_an); - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to del SA state\n", (nveul64_t)ret); - return -1; - } - - /* Store key table index returned to osd */ - *kt_idx = (nveu16_t)((existing_sc->sc_idx_start * OSI_MAX_NUM_SA) + - sc->curr_an); -#ifdef MACSEC_KEY_PROGRAM - /* 5. Key LUT */ - table_config = &kt_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - /* Each SC has OSI_MAX_NUM_SA's supported in HW */ - table_config->index = *kt_idx; - ret = macsec_kt_config(osi_core, &kt_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to del SAK\n", (nveul64_t)ret); - return -1; - } -#endif /* MACSEC_KEY_PROGRAM */ - - existing_sc->an_valid &= ~OSI_BIT(sc->curr_an); - - return 0; -} - -/** - * @brief print_error - Print error on failure - * - * @note - * Algorithm: - * - Print error if there is a failure - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] ret: value to judge if there is a failure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void print_error(const struct osi_core_priv_data *const osi_core, - nve32_t ret) -{ - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to config macsec\n", (nveul64_t)ret); - } -} - -/** - * @brief copy_rev_order - Helper function to copy from one buffer to the other - * - * @note - * Algorithm: - * - Copy from source buffer to dest buffer in reverse order - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[out] dst_buff: pointer to dest buffer - * @param[in] src_buff: pointer to source buffer - * @param[in] len: no. of bytes to be copied - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void copy_rev_order(nveu8_t *dst_buff, const nveu8_t *src_buff, nveu16_t len) -{ - nveu16_t i; - - /* Program in reverse order as per HW design */ - for (i = 0; i < len; i++) { - dst_buff[i] = src_buff[len - 1U - i]; - } -} - -/** - * @brief add_upd_sc - add or update an SC - * - * @note - * Algorithm: - * - If key programming is enabled, program the key if the command - * is to create SA - * - Create SA state lut - * - Create SC param lut - * - Create SCI lut - * - Create SC state lut if the command is to enable SA - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] existing_sc: Pointer to the existing sc - * @param[in] ctlr: Controller to be selected - * @param[out] kt_idx: Key index to be passed to osd - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t add_upd_sc(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu16_t ctlr, nveu16_t *kt_idx) -{ - struct osi_macsec_lut_config lut_config = {0}; - struct osi_macsec_table_config *table_config; - nve32_t ret; - nveu32_t i; -#ifdef MACSEC_KEY_PROGRAM - struct osi_macsec_kt_config kt_config = {0}; -#endif /* MACSEC_KEY_PROGRAM */ - - /* Store key table index returned to osd */ - *kt_idx = (nveu16_t)(((sc->sc_idx_start & 0xFFU) * OSI_MAX_NUM_SA) + sc->curr_an); - -#ifdef MACSEC_KEY_PROGRAM - /* 1. Key LUT */ - if (sc->flags == OSI_CREATE_SA) { - table_config = &kt_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - /* Each SC has OSI_MAX_NUM_SA's supported in HW */ - table_config->index = *kt_idx; - kt_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; - - copy_rev_order(kt_config.entry.sak, sc->sak, OSI_KEY_LEN_128); - copy_rev_order(kt_config.entry.h, sc->hkey, OSI_KEY_LEN_128); - - ret = macsec_kt_config(osi_core, &kt_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SAK\n", (nveul64_t)ret); - return -1; - } - } -#endif /* MACSEC_KEY_PROGRAM */ - - table_config = &lut_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - - /* 2. SA state LUT */ - lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (nveu16_t)(((sc->sc_idx_start & 0xFU) * - OSI_MAX_NUM_SA) + sc->curr_an); - lut_config.sa_state_out.next_pn = sc->next_pn; - lut_config.sa_state_out.lowest_pn = sc->lowest_pn; - lut_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SA state\n", (nveul64_t)ret); - goto err_sa_state; - } - - /* 3. SC param LUT */ - lut_config.flags = OSI_NONE; - lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; - table_config->index = (nveu16_t)(sc->sc_idx_start); - copy_rev_order(lut_config.sc_param_out.sci, sc->sci, OSI_SCI_LEN); - lut_config.sc_param_out.key_index_start = - ((sc->sc_idx_start & 0xFU) * - OSI_MAX_NUM_SA); - lut_config.sc_param_out.pn_max = OSI_PN_MAX_DEFAULT; - lut_config.sc_param_out.pn_threshold = OSI_PN_THRESHOLD_DEFAULT; - lut_config.sc_param_out.pn_window = sc->pn_window; - lut_config.sc_param_out.tci = OSI_TCI_DEFAULT; - lut_config.sc_param_out.vlan_in_clear = OSI_VLAN_IN_CLEAR_DEFAULT; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SC param\n", (nveul64_t)ret); - goto err_sc_param; - } - - /* 4. SCI LUT */ - lut_config.flags = OSI_NONE; - lut_config.lut_sel = OSI_LUT_SEL_SCI; - table_config->index = (nveu16_t)(sc->sc_idx_start); - /* Extract the mac sa from the SCI itself */ - copy_rev_order(lut_config.lut_in.sa, sc->sci, OSI_ETH_ALEN); - lut_config.flags |= OSI_LUT_FLAGS_SA_VALID; - lut_config.sci_lut_out.sc_index = sc->sc_idx_start; - for (i = 0; i < OSI_SCI_LEN; i++) { - lut_config.sci_lut_out.sci[i] = sc->sci[OSI_SCI_LEN - 1U - i]; - } - lut_config.sci_lut_out.an_valid = sc->an_valid; - - lut_config.flags |= OSI_LUT_FLAGS_ENTRY_VALID; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SCI LUT\n", (nveul64_t)ret); - goto err_sci; - } - - if (sc->flags == OSI_ENABLE_SA) { - /* 5. SC state LUT */ - lut_config.flags = OSI_NONE; - lut_config.lut_sel = OSI_LUT_SEL_SC_STATE; - table_config->index = (nveu16_t)(sc->sc_idx_start); - lut_config.sc_state_out.curr_an = sc->curr_an; - ret = macsec_lut_config(osi_core, &lut_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set SC state\n", (nveul64_t)ret); - goto err_sc_state; - } - } - return 0; - -err_sc_state: - /* Cleanup SCI LUT */ - osi_memset(&lut_config, 0, sizeof(lut_config)); - table_config = &lut_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - lut_config.lut_sel = OSI_LUT_SEL_SCI; - table_config->index = (nveu16_t)(sc->sc_idx_start); - ret = macsec_lut_config(osi_core, &lut_config); - print_error(osi_core, ret); - -err_sci: - /* cleanup SC param */ - osi_memset(&lut_config, 0, sizeof(lut_config)); - table_config = &lut_config.table_config; - table_config->ctlr_sel = ctlr; - lut_config.lut_sel = OSI_LUT_SEL_SC_PARAM; - table_config->index = (nveu16_t)(sc->sc_idx_start); - ret = macsec_lut_config(osi_core, &lut_config); - print_error(osi_core, ret); - -err_sc_param: - /* Cleanup SA state LUT */ - osi_memset(&lut_config, 0, sizeof(lut_config)); - table_config = &lut_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - lut_config.lut_sel = OSI_LUT_SEL_SA_STATE; - table_config->index = (nveu16_t)(((sc->sc_idx_start & 0xFU) * - OSI_MAX_NUM_SA) + sc->curr_an); - ret = macsec_lut_config(osi_core, &lut_config); - print_error(osi_core, ret); - -err_sa_state: -#ifdef MACSEC_KEY_PROGRAM - osi_memset(&kt_config, 0, sizeof(kt_config)); - table_config = &kt_config.table_config; - table_config->ctlr_sel = ctlr; - table_config->rw = OSI_LUT_WRITE; - table_config->index = *kt_idx; - ret = macsec_kt_config(osi_core, &kt_config); - print_error(osi_core, ret); -#endif /* MACSEC_KEY_PROGRAM */ - - return -1; -} - -/** - * @brief macsec_config_validate_inputs - Helper function to validate inputs - * - * @note - * Algorithm: - * - Returns -1 if the validation fails else returns 0 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] enable: parameter to enable/disable - * @param[in] ctlr: Parameter to indicate the controller - * @param[in] kt_idx: Pointer to kt_index - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t macsec_config_validate_inputs(nveu32_t enable, nveu16_t ctlr, - const nveu16_t *kt_idx) -{ - /* Validate inputs */ - if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || - ((ctlr != OSI_CTLR_SEL_TX) && (ctlr != OSI_CTLR_SEL_RX)) || - (kt_idx == OSI_NULL)) { - return -1; - } - return 0; -} - -/** - * @brief memcpy_sci_sak_hkey - Helper function to copy SC params - * - * @note - * Algorithm: - * - Copy SCI, sak and hkey from src to dst SC - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] src_sc: Pointer to source SC - * @param[out] dst_sc: Pointer to dest SC - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t memcpy_sci_sak_hkey(struct osi_macsec_sc_info *dst_sc, - struct osi_macsec_sc_info *src_sc) -{ - nve32_t ret = 0; - - ret = osi_memcpy(dst_sc->sci, src_sc->sci, OSI_SCI_LEN); - if (ret < OSI_NONE_SIGNED) { - goto failure; - } - ret = osi_memcpy(dst_sc->sak, src_sc->sak, OSI_KEY_LEN_128); - if (ret < OSI_NONE_SIGNED) { - goto failure; - } -#ifdef MACSEC_KEY_PROGRAM - ret = osi_memcpy(dst_sc->hkey, src_sc->hkey, OSI_KEY_LEN_128); - if (ret < OSI_NONE_SIGNED) { - goto failure; - } -#endif /* MACSEC_KEY_PROGRAM */ - -failure: - return ret; - -} - -/** - * @brief add_new_sc - Helper function to add new SC - * - * @note - * Algorithm: - * - Return -1 if new SC cannot be added because of max check - * - Return -1 if there is no available lot for storing new SC - * - Copy all the SC reltated parameters - * - Add a new SC to the LUTs, if failed return -1 - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] sc: Pointer to the sc that need to be added - * @param[in] ctlr: Controller to be selected - * @param[out] kt_idx: Key index to be passed to osd - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t add_new_sc(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu16_t ctlr, nveu16_t *kt_idx) -{ - nve32_t ret = 0; - struct osi_macsec_lut_status *lut_status_ptr; - nveu32_t avail_sc_idx = 0; - struct osi_macsec_sc_info *new_sc = OSI_NULL; - - lut_status_ptr = &osi_core->macsec_lut_status[ctlr]; - - if (lut_status_ptr->num_of_sc_used >= OSI_MAX_NUM_SC) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Err: Reached max SC LUT entries!\n", 0ULL); - return -1; - } - - avail_sc_idx = get_avail_sc_idx(osi_core, ctlr); - if (avail_sc_idx == OSI_MAX_NUM_SC) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Err: NO free SC Index\n", 0ULL); - return -1; - } - new_sc = &lut_status_ptr->sc_info[avail_sc_idx]; - ret = memcpy_sci_sak_hkey(new_sc, sc); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy Failed\n", 0ULL); - return -1; - } - new_sc->curr_an = sc->curr_an; - new_sc->next_pn = sc->next_pn; - new_sc->pn_window = sc->pn_window; - new_sc->flags = sc->flags; - - new_sc->sc_idx_start = avail_sc_idx; - new_sc->an_valid |= OSI_BIT((sc->curr_an & 0xFU)); - - if (add_upd_sc(osi_core, new_sc, ctlr, kt_idx) != - OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "failed to add new SC\n", 0ULL); - return -1; - } else { - /* Update lut status */ - lut_status_ptr->num_of_sc_used++; - LOG("%s: Added new SC ctlr: %u " - "Total active SCs: %u", - __func__, ctlr, - lut_status_ptr->num_of_sc_used); - return 0; - } -} - -/** - * @brief config_macsec - API to update LUTs for addition/deletion of SC/SA - * - * @note - * Algorithm: - * - Return -1 if inputs are invalid - * - Check if the Passed SC is already enabled - * - If not found - * - Add new SC if the request is to enable - * - Return failure if the request is to disable - * - If found - * - Update existing SC if request is to enable - * - Delete sc if the request is to disable - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * @param[in] sc: Pointer to the sc that need to be added/deleted/updated - * @param[in] ctlr: Controller to be selected - * @param[out] kt_idx: Key index to be passed to osd - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -static nve32_t config_macsec(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu32_t enable, nveu16_t ctlr, - nveu16_t *kt_idx) -{ - struct osi_macsec_sc_info *existing_sc = OSI_NULL; - struct osi_macsec_sc_info tmp_sc; - struct osi_macsec_sc_info *tmp_sc_p = &tmp_sc; - struct osi_macsec_lut_status *lut_status_ptr; - nve32_t ret; - - if (macsec_config_validate_inputs(enable, ctlr, kt_idx) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Input validation failed\n", 0ULL); - return -1; - } - - lut_status_ptr = &osi_core->macsec_lut_status[ctlr]; - /* 1. Find if SC is already existing in HW */ - existing_sc = find_existing_sc(osi_core, sc, ctlr); - if (existing_sc == OSI_NULL) { - if (enable == OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "trying to delete non-existing SC ?\n", - 0ULL); - return -1; - } else { - LOG("%s: Adding new SC/SA: ctlr: %hu", __func__, ctlr); - return add_new_sc(osi_core, sc, ctlr, kt_idx); - } - } else { - LOG("%s: Updating existing SC", __func__); - if (enable == OSI_DISABLE) { - LOG("%s: Deleting existing SA", __func__); - if (del_upd_sc(osi_core, existing_sc, sc, ctlr, kt_idx) != - OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "failed to del SA\n", 0ULL); - return -1; - } else { - if ((existing_sc->an_valid == OSI_NONE) && - (lut_status_ptr->num_of_sc_used != OSI_NONE)) { - lut_status_ptr->num_of_sc_used--; - osi_memset(existing_sc, OSI_NONE, - sizeof(*existing_sc)); - } - - return 0; - } - } else { - /* Take backup copy. - * Don't directly commit SC changes until LUT's are - * programmed successfully - */ - *tmp_sc_p = *existing_sc; - ret = memcpy_sci_sak_hkey(tmp_sc_p, sc); - if (ret < OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "memcpy Failed\n", 0ULL); - return -1; - } - tmp_sc_p->curr_an = sc->curr_an; - tmp_sc_p->next_pn = sc->next_pn; - tmp_sc_p->pn_window = sc->pn_window; - tmp_sc_p->flags = sc->flags; - - tmp_sc_p->an_valid |= OSI_BIT(sc->curr_an & 0x1FU); - - if (add_upd_sc(osi_core, tmp_sc_p, ctlr, kt_idx) != - OSI_NONE_SIGNED) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "failed to add new SA\n", 0ULL); - return -1; - } else { - LOG("%s: Updated new SC ctlr: %u " - "Total active SCs: %u", - __func__, ctlr, - lut_status_ptr->num_of_sc_used); - /* Now commit the changes */ - *existing_sc = *tmp_sc_p; - return 0; - } - } - } -} - -/** - * @brief osi_init_macsec_ops - macsec initialize operations - * - * @note - * Algorithm: - * - If virtualization is enabled initialize virt ops - * - Else - * - If macsec base is null return -1 - * - initialize with macsec ops - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. used param macsec_base - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_init_macsec_ops(struct osi_core_priv_data *const osi_core) -{ - static struct osi_macsec_core_ops virt_macsec_ops; - static struct osi_macsec_core_ops macsec_ops = { - .init = macsec_init, - .deinit = macsec_deinit, - .handle_ns_irq = macsec_handle_ns_irq, - .handle_s_irq = macsec_handle_s_irq, - .lut_config = macsec_lut_config, -#ifdef MACSEC_KEY_PROGRAM - .kt_config = macsec_kt_config, -#endif /* MACSEC_KEY_PROGRAM */ - .cipher_config = macsec_cipher_config, - .loopback_config = macsec_loopback_config, - .macsec_en = macsec_enable, - .config = config_macsec, - .read_mmc = macsec_read_mmc, - .dbg_buf_config = macsec_dbg_buf_config, - .dbg_events_config = macsec_dbg_events_config, - .get_sc_lut_key_index = macsec_get_key_index, - .update_mtu = macsec_update_mtu, - }; - - if (osi_core->use_virtualization == OSI_ENABLE) { - osi_core->macsec_ops = &virt_macsec_ops; - ivc_init_macsec_ops(osi_core->macsec_ops); - } else { - if (osi_core->macsec_base == OSI_NULL) { - return -1; - } - osi_core->macsec_ops = &macsec_ops; - } - return 0; -} - -/** - * @brief osi_macsec_init - Initialize the macsec controller - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Configure MTU, controller configs, interrupts, clear all LUT's and - * set BYP LUT entries for MKPDU and BC packets - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mtu: mtu to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_init(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->init != OSI_NULL)) { - return osi_core->macsec_ops->init(osi_core, mtu); - } - - return -1; -} - -/** - * @brief osi_macsec_deinit - De-Initialize the macsec controller - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Resets macsec global data structured and restores the mac confirguration - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_deinit(struct osi_core_priv_data *const osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->deinit != OSI_NULL)) { - return osi_core->macsec_ops->deinit(osi_core); - } - return -1; -} - -/** - * @brief osi_macsec_ns_isr - macsec non-secure irq handler - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - handles non-secure macsec interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void osi_macsec_ns_isr(struct osi_core_priv_data *const osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->handle_ns_irq != OSI_NULL)) { - osi_core->macsec_ops->handle_ns_irq(osi_core); - } -} - -/** - * @brief osi_macsec_s_isr - macsec secure irq handler - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - handles secure macsec interrupts - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -void osi_macsec_s_isr(struct osi_core_priv_data *const osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->handle_s_irq != OSI_NULL)) { - osi_core->macsec_ops->handle_s_irq(osi_core); - } -} - -/** - * @brief osi_macsec_config_lut - Read or write to macsec LUTs - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Reads or writes to MACSEC LUTs - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[out] lut_config: Pointer to the lut configuration - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_lut(struct osi_core_priv_data *const osi_core, - struct osi_macsec_lut_config *const lut_config) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->lut_config != OSI_NULL)) { - return osi_core->macsec_ops->lut_config(osi_core, lut_config); - } - - return -1; -} - -/** - * @brief osi_macsec_get_sc_lut_key_index - API to get key index for a given SCI - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - gets the key index for the given sci - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] sci: Pointer to sci that needs to be found - * @param[out] key_index: Pointer to key_index - * @param[in] ctlr: macsec controller selected - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_get_sc_lut_key_index(struct osi_core_priv_data *const osi_core, - nveu8_t *sci, nveu32_t *key_index, - nveu16_t ctlr) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->get_sc_lut_key_index != OSI_NULL)) { - return osi_core->macsec_ops->get_sc_lut_key_index(osi_core, sci, key_index, - ctlr); - } - - return -1; -} - -/** - * @brief osi_macsec_update_mtu - Update the macsec mtu in run-time - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates the macsec mtu - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] mtu: mtu that needs to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_update_mtu(struct osi_core_priv_data *const osi_core, - nveu32_t mtu) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->update_mtu != OSI_NULL)) { - return osi_core->macsec_ops->update_mtu(osi_core, mtu); - } - - return -1; -} - -#ifdef MACSEC_KEY_PROGRAM -/** - * @brief osi_macsec_config_kt - API to read or update the keys - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Read or write the keys - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] kt_config: Keys that needs to be programmed - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_kt(struct osi_core_priv_data *const osi_core, - struct osi_macsec_kt_config *const kt_config) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->kt_config != OSI_NULL) && - (kt_config != OSI_NULL)) { - return osi_core->macsec_ops->kt_config(osi_core, kt_config); - } - - return -1; -} -#endif /* MACSEC_KEY_PROGRAM */ - -/** - * @brief osi_macsec_cipher_config - API to update the cipher - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates cipher to use - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] cipher: Cipher suit to be used - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_cipher_config(struct osi_core_priv_data *const osi_core, - nveu32_t cipher) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->cipher_config != OSI_NULL)) { - return osi_core->macsec_ops->cipher_config(osi_core, cipher); - } - - return -1; -} - -/** - * @brief osi_macsec_loopback - API to enable/disable macsec loopback - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Enables/disables macsec loopback - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] enable: parameter to enable or disable - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_loopback(struct osi_core_priv_data *const osi_core, - nveu32_t enable) -{ - - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->loopback_config != OSI_NULL)) { - return osi_core->macsec_ops->loopback_config(osi_core, enable); - } - - return -1; -} - -/** - * @brief osi_macsec_en - API to enable/disable macsec - * - * @note - * Algorithm: - * - Return -1 if passed enable param is invalid - * - Return -1 if osi core or ops is null - * - Enables/disables macsec - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] enable: parameter to enable or disable - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_en(struct osi_core_priv_data *const osi_core, - nveu32_t enable) -{ - if (((enable & OSI_MACSEC_TX_EN) != OSI_MACSEC_TX_EN) && - ((enable & OSI_MACSEC_RX_EN) != OSI_MACSEC_RX_EN) && - (enable != OSI_DISABLE)) { - return -1; - } - - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->macsec_en != OSI_NULL)) { - return osi_core->macsec_ops->macsec_en(osi_core, enable); - } - - return -1; -} - -/** - * @brief osi_macsec_config - Updates SC or SA in the macsec - * - * @note - * Algorithm: - * - Return -1 if passed params are invalid - * - Return -1 if osi core or ops is null - * - Update/add/delete SC/SA - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] sc: Pointer to the sc that needs to be added/deleted/updated - * @param[in] ctlr: Controller selected - * @param[out] kt_idx: Pointer to the kt_index passed to OSD - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config(struct osi_core_priv_data *const osi_core, - struct osi_macsec_sc_info *const sc, - nveu32_t enable, nveu16_t ctlr, - nveu16_t *kt_idx) -{ - if (((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) || - (ctlr > OSI_CTLR_SEL_MAX) || (kt_idx == OSI_NULL)) { - return -1; - } - - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->config != OSI_NULL) && (sc != OSI_NULL)) { - return osi_core->macsec_ops->config(osi_core, sc, - enable, ctlr, kt_idx); - } - - return -1; -} - -/** - * @brief osi_macsec_read_mmc - Updates the mmc counters - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Updates the mcc counters in osi_core structure - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[out] osi_core: OSI core private data structure - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_read_mmc(struct osi_core_priv_data *const osi_core) -{ - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->read_mmc != OSI_NULL)) { - osi_core->macsec_ops->read_mmc(osi_core); - return 0; - } - - return -1; -} - -/** - * @brief osi_macsec_config_dbg_buf - Reads the debug buffer captured - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Reads the dbg buffers captured - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[out] dbg_buf_config: dbg buffer data captured - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_config_dbg_buf( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->dbg_buf_config != OSI_NULL)) { - return osi_core->macsec_ops->dbg_buf_config(osi_core, - dbg_buf_config); - } - - return -1; -} - -/** - * @brief osi_macsec_dbg_events_config - Enables debug buffer events - * - * @note - * Algorithm: - * - Return -1 if osi core or ops is null - * - Enables specific events to capture debug buffers - * - Refer to MACSEC column of <<******, (sequence diagram)>> for API details. - * - TraceID: *********** - * - * @param[in] osi_core: OSI core private data structure - * @param[in] dbg_buf_config: dbg buffer data captured - * - * @pre MACSEC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure - */ -nve32_t osi_macsec_dbg_events_config( - struct osi_core_priv_data *const osi_core, - struct osi_macsec_dbg_buf_config *const dbg_buf_config) -{ - - if ((osi_core != OSI_NULL) && (osi_core->macsec_ops != OSI_NULL) && - (osi_core->macsec_ops->dbg_events_config != OSI_NULL)) { - return osi_core->macsec_ops->dbg_events_config(osi_core, - dbg_buf_config); - } - - return -1; -} - -#endif /* MACSEC_SUPPORT */ diff --git a/osi/core/macsec.h b/osi/core/macsec.h deleted file mode 100644 index 7d027d0..0000000 --- a/osi/core/macsec.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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 INCLUDED_MACSEC_H -#define INCLUDED_MACSEC_H - -#ifdef DEBUG_MACSEC -#define HKEY2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13], (a)[14], (a)[15] -#define HKEYSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" - -#define KEY2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7], (a)[8], (a)[9], (a)[10], (a)[11], (a)[12], (a)[13], (a)[14], (a)[15] -#define KEYSTR "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" -#endif /* DEBUG_MACSEC */ - -#define MAX_U64_VAL 0xFFFFFFFFFFFFFFFFU - -#define CERT_C__POST_INC__U64(a)\ - {\ - if ((a) < MAX_U64_VAL) {\ - (a)++;\ - } else {\ - (a) = 0;\ - } \ - } \ - -/** - * @addtogroup MACsec AMAP - * - * @brief MACsec controller register offsets - * @{ - */ -#define MACSEC_GCM_KEYTABLE_CONFIG 0x0000 -#define MACSEC_GCM_KEYTABLE_DATA(x) ((0x0004U) + ((x) * 4U)) -#define MACSEC_RX_ICV_ERR_CNTRL 0x4000 -#define MACSEC_INTERRUPT_COMMON_SR 0x4004 -#define MACSEC_TX_IMR 0x4008 -#define MACSEC_TX_ISR 0x400C -#define MACSEC_RX_IMR 0x4048 -#define MACSEC_RX_ISR 0x404C -#define MACSEC_TX_SC_PN_THRESHOLD_STATUS0_0 0x4018 -#define MACSEC_TX_SC_PN_THRESHOLD_STATUS1_0 0x401C -#define MACSEC_TX_SC_PN_EXHAUSTED_STATUS0_0 0x4024 -#define MACSEC_TX_SC_PN_EXHAUSTED_STATUS1_0 0x4028 -#define MACSEC_TX_SC_ERROR_INTERRUPT_STATUS_0 0x402C -#define MACSEC_RX_SC_PN_EXHAUSTED_STATUS0_0 0x405C -#define MACSEC_RX_SC_PN_EXHAUSTED_STATUS1_0 0x4060 -#define MACSEC_RX_SC_REPLAY_ERROR_STATUS0_0 0x4090 -#define MACSEC_RX_SC_REPLAY_ERROR_STATUS1_0 0x4094 -#define MACSEC_STATS_CONTROL_0 0x900C -#define MACSEC_TX_PKTS_UNTG_LO_0 0x9010 -#define MACSEC_TX_OCTETS_PRTCTD_LO_0 0x9018 -#define MACSEC_TX_PKTS_TOO_LONG_LO_0 0x9020 -#define MACSEC_TX_PKTS_PROTECTED_SCx_LO_0(x) ((0x9028UL) + ((x) * 8UL)) -#define MACSEC_RX_PKTS_NOTG_LO_0 0x90B0 -#define MACSEC_RX_PKTS_UNTG_LO_0 0x90A8 -#define MACSEC_RX_PKTS_BADTAG_LO_0 0x90B8 -#define MACSEC_RX_PKTS_NOSA_LO_0 0x90C0 -#define MACSEC_RX_PKTS_NOSAERROR_LO_0 0x90C8 -#define MACSEC_RX_PKTS_OVRRUN_LO_0 0x90D0 -#define MACSEC_RX_OCTETS_VLDTD_LO_0 0x90D8 -#define MACSEC_RX_PKTS_LATE_SCx_LO_0(x) ((0x90E0UL) + ((x) * 8UL)) -#define MACSEC_RX_PKTS_NOTVALID_SCx_LO_0(x) ((0x9160UL) + ((x) * 8UL)) -#define MACSEC_RX_PKTS_OK_SCx_LO_0(x) ((0x91E0UL) + ((x) * 8UL)) - - -#define MACSEC_CONTROL0 0xD000 -#define MACSEC_LUT_CONFIG 0xD004 -#define MACSEC_LUT_DATA(x) ((0xD008U) + ((x) * 4U)) -#define MACSEC_TX_BYP_LUT_VALID 0xD024 -#define MACSEC_TX_SCI_LUT_VALID 0xD028 -#define MACSEC_RX_BYP_LUT_VALID 0xD02C -#define MACSEC_RX_SCI_LUT_VALID 0xD030 - -#define MACSEC_COMMON_IMR 0xD054 -#define MACSEC_COMMON_ISR 0xD058 -#define MACSEC_TX_SC_KEY_INVALID_STS0_0 0xD064 -#define MACSEC_TX_SC_KEY_INVALID_STS1_0 0xD068 -#define MACSEC_RX_SC_KEY_INVALID_STS0_0 0xD080 -#define MACSEC_RX_SC_KEY_INVALID_STS1_0 0xD084 - -#define MACSEC_TX_DEBUG_CONTROL_0 0xD098 -#define MACSEC_TX_DEBUG_TRIGGER_EN_0 0xD09C -#define MACSEC_TX_DEBUG_STATUS_0 0xD0C4 -#define MACSEC_DEBUG_BUF_CONFIG_0 0xD0C8 -#define MACSEC_DEBUG_BUF_DATA_0(x) ((0xD0CCU) + ((x) * 4U)) -#define MACSEC_RX_DEBUG_CONTROL_0 0xD0DC -#define MACSEC_RX_DEBUG_TRIGGER_EN_0 0xD0E0 -#define MACSEC_RX_DEBUG_STATUS_0 0xD0F8 - -#define MACSEC_CONTROL1 0xE000 -#define MACSEC_GCM_AES_CONTROL_0 0xE004 -#define MACSEC_TX_MTU_LEN 0xE008 -#define MACSEC_TX_SOT_DELAY 0xE010 -#define MACSEC_RX_MTU_LEN 0xE014 -#define MACSEC_RX_SOT_DELAY 0xE01C -/** @} */ - -/** - * @addtogroup MACSEC_GCM_KEYTABLE_CONFIG register - * - * @brief Bit definitions of MACSEC_GCM_KEYTABLE_CONFIG register - * @{ - */ -#define MACSEC_KT_CONFIG_UPDATE OSI_BIT(31) -#define MACSEC_KT_CONFIG_CTLR_SEL OSI_BIT(25) -#define MACSEC_KT_CONFIG_RW OSI_BIT(24) -#define MACSEC_KT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ - OSI_BIT(1) | OSI_BIT(0)) -#define MACSEC_KT_ENTRY_VALID OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_GCM_KEYTABLE_DATA registers - * - * @brief Bit definitions of MACSEC_GCM_KEYTABLE_DATA register & helpful macros - * @{ - */ -#define MACSEC_KT_DATA_REG_CNT 13U -#define MACSEC_KT_DATA_REG_SAK_CNT 8U -#define MACSEC_KT_DATA_REG_H_CNT 4U -/** @} */ - -/** - * @addtogroup MACSEC_LUT_CONFIG register - * - * @brief Bit definitions of MACSEC_LUT_CONFIG register - * @{ - */ -#define MACSEC_LUT_CONFIG_UPDATE OSI_BIT(31) -#define MACSEC_LUT_CONFIG_CTLR_SEL OSI_BIT(25) -#define MACSEC_LUT_CONFIG_RW OSI_BIT(24) -#define MACSEC_LUT_CONFIG_LUT_SEL_MASK (OSI_BIT(18) | OSI_BIT(17) |\ - OSI_BIT(16)) -#define MACSEC_LUT_CONFIG_LUT_SEL_SHIFT 16 -#define MACSEC_LUT_CONFIG_INDEX_MASK (OSI_BIT(4) | OSI_BIT(3) | OSI_BIT(2) |\ - OSI_BIT(1) | OSI_BIT(0)) -/** @} */ -/** - * @addtogroup INTERRUPT_COMMON_STATUS register - * - * @brief Bit definitions of MACSEC_INTERRUPT_COMMON_STATUS register - * @{ - */ -#define MACSEC_COMMON_SR_SFTY_ERR OSI_BIT(2) -#define MACSEC_COMMON_SR_RX OSI_BIT(1) -#define MACSEC_COMMON_SR_TX OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_CONTROL0 register - * - * @brief Bit definitions of MACSEC_CONTROL0 register - * @{ - */ -#define MACSEC_TX_LKUP_MISS_NS_INTR OSI_BIT(24) -#define MACSEC_RX_LKUP_MISS_NS_INTR OSI_BIT(23) -#define MACSEC_VALIDATE_FRAMES_MASK (OSI_BIT(22) | OSI_BIT(21)) -#define MACSEC_VALIDATE_FRAMES_STRICT OSI_BIT(22) -#define MACSEC_RX_REPLAY_PROT_EN OSI_BIT(20) -#define MACSEC_RX_LKUP_MISS_BYPASS OSI_BIT(19) -#define MACSEC_RX_EN OSI_BIT(16) -#define MACSEC_TX_LKUP_MISS_BYPASS OSI_BIT(3) -#define MACSEC_TX_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_CONTROL1 register - * - * @brief Bit definitions of MACSEC_CONTROL1 register - * @{ - */ -#define MACSEC_LOOPBACK_MODE_EN OSI_BIT(31) -#define MACSEC_RX_MTU_CHECK_EN OSI_BIT(16) -#define MACSEC_TX_LUT_PRIO_BYP OSI_BIT(2) -#define MACSEC_TX_MTU_CHECK_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_GCM_AES_CONTROL_0 register - * - * @brief Bit definitions of MACSEC_GCM_AES_CONTROL_0 register - * @{ - */ -#define MACSEC_RX_AES_MODE_MASK (OSI_BIT(17) | OSI_BIT(16)) -#define MACSEC_RX_AES_MODE_AES128 0x0U -#define MACSEC_RX_AES_MODE_AES256 OSI_BIT(17) -#define MACSEC_TX_AES_MODE_MASK (OSI_BIT(1) | OSI_BIT(0)) -#define MACSEC_TX_AES_MODE_AES128 0x0U -#define MACSEC_TX_AES_MODE_AES256 OSI_BIT(1) -/** @} */ - -/** - * @addtogroup MACSEC_COMMON_IMR register - * - * @brief Bit definitions of MACSEC_INTERRUPT_MASK register - * @{ - */ -#define MACSEC_SECURE_REG_VIOL_INT_EN OSI_BIT(31) -#define MACSEC_RX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(17) -#define MACSEC_RX_LKUP_MISS_INT_EN OSI_BIT(16) -#define MACSEC_TX_UNINIT_KEY_SLOT_INT_EN OSI_BIT(1) -#define MACSEC_TX_LKUP_MISS_INT_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_TX_IMR register - * - * @brief Bit definitions of TX_INTERRUPT_MASK register - * @{ - */ -#define MACSEC_TX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#define MACSEC_TX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define MACSEC_TX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define MACSEC_TX_SC_AN_NOT_VALID_INT_EN OSI_BIT(17) -#define MACSEC_TX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define MACSEC_TX_PN_EXHAUSTED_INT_EN OSI_BIT(1) -#define MACSEC_TX_PN_THRSHLD_RCHD_INT_EN OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_RX_IMR register - * - * @brief Bit definitions of RX_INTERRUPT_MASK register - * @{ - */ -#define MACSEC_RX_DBG_BUF_CAPTURE_DONE_INT_EN OSI_BIT(22) -#define MACSEC_RX_ICV_ERROR_INT_EN OSI_BIT(21) -#define RX_REPLAY_ERROR_INT_EN OSI_BIT(20) -#define MACSEC_RX_MTU_CHECK_FAIL_INT_EN OSI_BIT(19) -#define MACSEC_RX_AES_GCM_BUF_OVF_INT_EN OSI_BIT(18) -#define MACSEC_RX_MAC_CRC_ERROR_INT_EN OSI_BIT(16) -#define MACSEC_RX_PN_EXHAUSTED_INT_EN OSI_BIT(1) -/** @} */ - -/** - * @addtogroup MACSEC_COMMON_ISR register - * - * @brief Bit definitions of MACSEC_INTERRUPT_STATUS register - * @{ - */ -#define MACSEC_SECURE_REG_VIOL OSI_BIT(31) -#define MACSEC_RX_UNINIT_KEY_SLOT OSI_BIT(17) -#define MACSEC_RX_LKUP_MISS OSI_BIT(16) -#define MACSEC_TX_UNINIT_KEY_SLOT OSI_BIT(1) -#define MACSEC_TX_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_TX_ISR register - * - * @brief Bit definitions of TX_INTERRUPT_STATUS register - * @{ - */ -#define MACSEC_TX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#define MACSEC_TX_MTU_CHECK_FAIL OSI_BIT(19) -#define MACSEC_TX_AES_GCM_BUF_OVF OSI_BIT(18) -#define MACSEC_TX_SC_AN_NOT_VALID OSI_BIT(17) -#define MACSEC_TX_MAC_CRC_ERROR OSI_BIT(16) -#define MACSEC_TX_PN_EXHAUSTED OSI_BIT(1) -#define MACSEC_TX_PN_THRSHLD_RCHD OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_RX_ISR register - * - * @brief Bit definitions of RX_INTERRUPT_STATUS register - * @{ - */ -#define MACSEC_RX_DBG_BUF_CAPTURE_DONE OSI_BIT(22) -#define MACSEC_RX_ICV_ERROR OSI_BIT(21) -#define MACSEC_RX_REPLAY_ERROR OSI_BIT(20) -#define MACSEC_RX_MTU_CHECK_FAIL OSI_BIT(19) -#define MACSEC_RX_AES_GCM_BUF_OVF OSI_BIT(18) -#define MACSEC_RX_MAC_CRC_ERROR OSI_BIT(16) -#define MACSEC_RX_PN_EXHAUSTED OSI_BIT(1) -/** @} */ - -/** - * @addtogroup MACSEC_STATS_CONTROL_0 register - * - * @brief Bit definitions of MACSEC_STATS_CONTROL_0 register - * @{ - */ -#define MACSEC_STATS_CONTROL0_CNT_RL_OVR_CPY OSI_BIT(1) -/** @} */ - -/** - * @addtogroup MACSEC_DEBUG_BUF_CONFIG_0 register - * - * @brief Bit definitions of MACSEC_DEBUG_BUF_CONFIG_0 register - * @{ - */ -#define MACSEC_DEBUG_BUF_CONFIG_0_UPDATE OSI_BIT(31) -#define MACSEC_DEBUG_BUF_CONFIG_0_CTLR_SEL OSI_BIT(25) -#define MACSEC_DEBUG_BUF_CONFIG_0_RW OSI_BIT(24) -#define MACSEC_DEBUG_BUF_CONFIG_0_IDX_MASK (OSI_BIT(0) | OSI_BIT(1) | \ - OSI_BIT(2) | OSI_BIT(3)) -/** @} */ - -/** - * @addtogroup MACSEC_TX_DEBUG_TRIGGER_EN_0 register - * - * @brief Bit definitions of MACSEC_TX_DEBUG_TRIGGER_EN_0 register - * @{ - */ -#define MACSEC_TX_DBG_CAPTURE OSI_BIT(10) -#define MACSEC_TX_DBG_ICV_CORRUPT OSI_BIT(9) -#define MACSEC_TX_DBG_CRC_CORRUPT OSI_BIT(8) -#define MACSEC_TX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define MACSEC_TX_DBG_AN_NOT_VALID OSI_BIT(1) -#define MACSEC_TX_DBG_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_RX_DEBUG_TRIGGER_EN_0 register - * - * @brief Bit definitions of MACSEC_RX_DEBUG_TRIGGER_EN_0 register - * @{ - */ -#define MACSEC_RX_DBG_CAPTURE OSI_BIT(10) -#define MACSEC_RX_DBG_ICV_ERROR OSI_BIT(9) -#define MACSEC_RX_DBG_CRC_CORRUPT OSI_BIT(8) -#define MACSEC_RX_DBG_REPLAY_ERR OSI_BIT(3) -#define MACSEC_RX_DBG_KEY_NOT_VALID OSI_BIT(2) -#define MACSEC_RX_DBG_LKUP_MISS OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MACSEC_TX_DEBUG_CONTROL_0 register - * - * @brief Bit definitions of MACSEC_TX_DEBUG_CONTROL_0 register - * @{ - */ -#define MACSEC_TX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) -/** @} */ - -/** - * @addtogroup MACSEC_RX_DEBUG_CONTROL_0 register - * - * @brief Bit definitions of MACSEC_RX_DEBUG_CONTROL_0 register - * @{ - */ -#define MACSEC_RX_DEBUG_CONTROL_0_START_CAP OSI_BIT(31) -/** @} */ - -#define MTU_LENGTH_MASK 0xFFFFU -#define SOT_LENGTH_MASK 0xFFU -#define EQOS_MACSEC_SOT_DELAY 0x4EU - -/** - * @addtogroup TX/RX_BYP/SCI_LUT_VALID register - * - * @brief Bit definitions of LUT_VALID registers - * @{ - */ -/** @} */ - -/** - * @addtogroup TX/RX LUT bit fields in LUT_DATA registers - * - * @brief Helper macros for LUT data programming - * @{ - */ -#define MACSEC_LUT_DATA_REG_CNT 7U -/* Bit Offsets for LUT DATA[x] registers for various lookup field masks */ -/* DA mask bits in LUT_DATA[1] register */ -#define MACSEC_LUT_DA_BYTE0_INACTIVE OSI_BIT(16) -#define MACSEC_LUT_DA_BYTE1_INACTIVE OSI_BIT(17) -#define MACSEC_LUT_DA_BYTE2_INACTIVE OSI_BIT(18) -#define MACSEC_LUT_DA_BYTE3_INACTIVE OSI_BIT(19) -#define MACSEC_LUT_DA_BYTE4_INACTIVE OSI_BIT(20) -#define MACSEC_LUT_DA_BYTE5_INACTIVE OSI_BIT(21) -/* SA mask bits in LUT_DATA[3] register */ -#define MACSEC_LUT_SA_BYTE0_INACTIVE OSI_BIT(6) -#define MACSEC_LUT_SA_BYTE1_INACTIVE OSI_BIT(7) -#define MACSEC_LUT_SA_BYTE2_INACTIVE OSI_BIT(8) -#define MACSEC_LUT_SA_BYTE3_INACTIVE OSI_BIT(9) -#define MACSEC_LUT_SA_BYTE4_INACTIVE OSI_BIT(10) -#define MACSEC_LUT_SA_BYTE5_INACTIVE OSI_BIT(11) -/* Ether type mask in LUT_DATA[3] register */ -#define MACSEC_LUT_ETHTYPE_INACTIVE OSI_BIT(28) -/* VLAN PCP mask in LUT_DATA[4] register */ -#define MACSEC_LUT_VLAN_PCP_INACTIVE OSI_BIT(0) -/* VLAN ID mask in LUT_DATA[4] register */ -#define MACSEC_LUT_VLAN_ID_INACTIVE OSI_BIT(13) -/* VLAN mask in LUT_DATA[4] register */ -#define MACSEC_LUT_VLAN_ACTIVE OSI_BIT(14) -/* Byte pattern masks in LUT_DATA[4] register */ -#define MACSEC_LUT_BYTE0_PATTERN_INACTIVE OSI_BIT(29) -/* Byte pattern masks in LUT_DATA[5] register */ -#define MACSEC_LUT_BYTE1_PATTERN_INACTIVE OSI_BIT(12) -#define MACSEC_LUT_BYTE2_PATTERN_INACTIVE OSI_BIT(27) -/* Byte pattern masks in LUT_DATA[6] register */ -#define MACSEC_LUT_BYTE3_PATTERN_INACTIVE OSI_BIT(10) -/* Preemptable packet in LUT_DATA[6] register */ -#define MACSEC_LUT_PREEMPT OSI_BIT(11) -/* Preempt mask in LUT_DATA[6] register */ -#define MACSEC_LUT_PREEMPT_INACTIVE OSI_BIT(12) -/* Controlled port mask in LUT_DATA[6] register */ -#define MACSEC_LUT_CONTROLLED_PORT OSI_BIT(13) -/* DVLAN packet in LUT_DATA[6] register */ -#define MACSEC_BYP_LUT_DVLAN_PKT OSI_BIT(14) -/* DVLAN outer/inner tag select in LUT_DATA[6] register */ -#define BYP_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(15) -/* AN valid bits for SCI LUT in LUT_DATA[6] register */ -#define MACSEC_LUT_AN0_VALID OSI_BIT(13) -#define MACSEC_LUT_AN1_VALID OSI_BIT(14) -#define MACSEC_LUT_AN2_VALID OSI_BIT(15) -#define MACSEC_LUT_AN3_VALID OSI_BIT(16) -/* DVLAN packet in LUT_DATA[6] register */ -#define MACSEC_TX_SCI_LUT_DVLAN_PKT OSI_BIT(21) -/* DVLAN outer/inner tag select in LUT_DATA[6] register */ -#define MACSEC_TX_SCI_LUT_DVLAN_OUTER_INNER_TAG_SEL OSI_BIT(22) -/* SA State LUT entry valid in LUT_DATA[0] register */ -#define MACSEC_SA_STATE_LUT_ENTRY_VALID OSI_BIT(0) - -/* Preemptable packet in LUT_DATA[2] register for Rx SCI */ -#define MACSEC_RX_SCI_LUT_PREEMPT OSI_BIT(8) -/* Preempt mask in LUT_DATA[2] register for Rx SCI */ -#define MACSEC_RX_SCI_LUT_PREEMPT_INACTIVE OSI_BIT(9) -/** @} */ - -/* debug buffer data read/write length */ -#define DBG_BUF_LEN 4U -#define INTEGER_LEN 4U - -#endif /* INCLUDED_MACSEC_H */ diff --git a/osi/core/mgbe_core.c b/osi/core/mgbe_core.c deleted file mode 100644 index 18d03e2..0000000 --- a/osi/core/mgbe_core.c +++ /dev/null @@ -1,6284 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "../osi/common/common.h" -#include "../osi/common/type.h" -#include -#include -#include -#include "mgbe_core.h" -#include "core_local.h" -#include "xpcs.h" -#include "mgbe_mmc.h" -#include "vlan_filter.h" -#include "core_common.h" - -/** - * @brief mgbe_ptp_tsc_capture - read PTP and TSC registers - * - * Algorithm: - * - write 1 to MGBE_WRAP_SYNC_TSC_PTP_CAPTURE_0 - * - wait till MGBE_WRAP_SYNC_TSC_PTP_CAPTURE_0 is 0x0 - * - read and return following registers - * MGBE_WRAP _TSC_CAPTURE_LOW_0 - * MGBE_WRAP _TSC_CAPTURE_HIGH_0 - * MGBE_WRAP _PTP_CAPTURE_LOW_0 - * MGBE_WRAP _PTP_CAPTURE_HIGH_0 - * - * @param[in] base: MGBE virtual base address. - * @param[out]: osi_core_ptp_tsc_data register - * - * @note MAC needs to be out of reset and proper clock configured. TSC and PTP - * registers should be configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_ptp_tsc_capture(struct osi_core_priv_data *const osi_core, - struct osi_core_ptp_tsc_data *data) -{ - nveu32_t retry = 20U; - nveu32_t count = 0U, val = 0U; - nve32_t cond = COND_NOT_MET; - nve32_t ret = -1; - - osi_writela(osi_core, OSI_ENABLE, (nveu8_t *)osi_core->base + - MGBE_WRAP_SYNC_TSC_PTP_CAPTURE); - - /* Poll Until Poll Condition */ - while (cond == COND_NOT_MET) { - if (count > retry) { - /* Max retries reached */ - goto done; - } - - count++; - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_SYNC_TSC_PTP_CAPTURE); - if ((val & OSI_ENABLE) == OSI_NONE) { - cond = COND_MET; - } else { - /* delay if SWR is set */ - osi_core->osd_ops.udelay(1U); - } - } - - data->tsc_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_TSC_CAPTURE_LOW); - data->tsc_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_TSC_CAPTURE_HIGH); - data->ptp_low_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_PTP_CAPTURE_LOW); - data->ptp_high_bits = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_PTP_CAPTURE_HIGH); - ret = 0; -done: - return ret; -} - -/** - * @brief mgbe_config_fw_err_pkts - Configure forwarding of error packets - * - * Algorithm: When FEP bit is reset, the Rx queue drops packets with - * error status (CRC error, GMII_ER, watchdog timeout, or overflow). - * When FEP bit is set, all packets except the runt error packets - * are forwarded to the application or DMA. - * - * @param[in] addr: Base address indicating the start of memory mapped IO - * region of the MAC. - * @param[in] qinx: Q index - * @param[in] enable_fw_err_pkts: Enable or Disable the forwarding of error - * packets - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_fw_err_pkts(struct osi_core_priv_data *osi_core, - const unsigned int qinx, - const unsigned int enable_fw_err_pkts) -{ - unsigned int val; - - /* Check for valid enable_fw_err_pkts and qinx values */ - if ((enable_fw_err_pkts!= OSI_ENABLE && - enable_fw_err_pkts != OSI_DISABLE) || - (qinx >= OSI_MGBE_MAX_NUM_CHANS)) { - return -1; - } - - /* Read MTL RXQ Operation_Mode Register */ - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_CHX_RX_OP_MODE(qinx)); - - /* enable_fw_err_pkts, 1 is for enable and 0 is for disable */ - if (enable_fw_err_pkts == OSI_ENABLE) { - /* When enable_fw_err_pkts bit is set, all packets except - * the runt error packets are forwarded to the application - * or DMA. - */ - val |= MGBE_MTL_RXQ_OP_MODE_FEP; - } else { - /* When this bit is reset, the Rx queue drops packets with error - * status (CRC error, GMII_ER, watchdog timeout, or overflow) - */ - val &= ~MGBE_MTL_RXQ_OP_MODE_FEP; - } - - /* Write to FEP bit of MTL RXQ Operation Mode Register to enable or - * disable the forwarding of error packets to DMA or application. - */ - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_MTL_CHX_RX_OP_MODE(qinx)); - - return 0; -} - -/** - * @brief mgbe_poll_for_swr - Poll for software reset (SWR bit in DMA Mode) - * - * Algorithm: CAR reset will be issued through MAC reset pin. - * Waits for SWR reset to be cleared in DMA Mode register. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_poll_for_swr(struct osi_core_priv_data *const osi_core) -{ - void *addr = osi_core->base; - nveu32_t retry = 1000; - nveu32_t count; - nveu32_t dma_bmr = 0; - nve32_t cond = 1; - nveu32_t pre_si = osi_core->pre_si; - - /* Performing software reset */ - if (pre_si == OSI_ENABLE) { - osi_writela(osi_core, OSI_ENABLE, - (nveu8_t *)addr + MGBE_DMA_MODE); - } - - /* Poll Until Poll Condition */ - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - - dma_bmr = osi_readla(osi_core, (nveu8_t *)addr + MGBE_DMA_MODE); - if ((dma_bmr & MGBE_DMA_MODE_SWR) == OSI_NONE) { - cond = 0; - } else { - /* sleep if SWR is set */ - osi_core->osd_ops.msleep(1U); - } - } - - return 0; -} - -/** - * @brief mgbe_calculate_per_queue_fifo - Calculate per queue FIFO size - * - * Algorithm: Total Tx/Rx FIFO size which is read from - * MAC HW is being shared equally among the queues that are - * configured. - * - * @param[in] fifo_size: Total Tx/RX HW FIFO size. - * @param[in] queue_count: Total number of Queues configured. - * - * @note MAC has to be out of reset. - * - * @retval Queue size that need to be programmed. - */ -static nveu32_t mgbe_calculate_per_queue_fifo(nveu32_t fifo_size, - nveu32_t queue_count) -{ - nveu32_t q_fifo_size = 0; /* calculated fifo size per queue */ - nveu32_t p_fifo = 0; /* per queue fifo size program value */ - - if (queue_count == 0U) { - return 0U; - } - - /* calculate Tx/Rx fifo share per queue */ - switch (fifo_size) { - case 0: - case 1: - case 2: - case 3: - q_fifo_size = FIFO_SIZE_KB(1U); - break; - case 4: - q_fifo_size = FIFO_SIZE_KB(2U); - break; - case 5: - q_fifo_size = FIFO_SIZE_KB(4U); - break; - case 6: - q_fifo_size = FIFO_SIZE_KB(8U); - break; - case 7: - q_fifo_size = FIFO_SIZE_KB(16U); - break; - case 8: - q_fifo_size = FIFO_SIZE_KB(32U); - break; - case 9: - q_fifo_size = FIFO_SIZE_KB(64U); - break; - case 10: - q_fifo_size = FIFO_SIZE_KB(128U); - break; - case 11: - q_fifo_size = FIFO_SIZE_KB(256U); - break; - case 12: - /* Size mapping not found for 192KB, so assigned 12 */ - q_fifo_size = FIFO_SIZE_KB(192U); - break; - default: - q_fifo_size = FIFO_SIZE_KB(1U); - break; - } - - q_fifo_size = q_fifo_size / queue_count; - - if (q_fifo_size < UINT_MAX) { - p_fifo = (q_fifo_size / 256U) - 1U; - } - - return p_fifo; -} - -/** - * @brief mgbe_poll_for_mac_accrtl - Poll for Indirect Access control and status - * register operations complete. - * - * Algorithm: Waits for waits for transfer busy bit to be cleared in - * MAC Indirect address control register to complete operations. - * - * @param[in] addr: MGBE virtual base address. - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_poll_for_mac_acrtl(struct osi_core_priv_data *osi_core) -{ - nveu32_t count = 0U; - nveu32_t mac_indir_addr_ctrl = 0U; - - /* Poll Until MAC_Indir_Access_Ctrl OB is clear */ - while (count < MGBE_MAC_INDIR_AC_OB_RETRY) { - mac_indir_addr_ctrl = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_INDIR_AC); - if ((mac_indir_addr_ctrl & MGBE_MAC_INDIR_AC_OB) == OSI_NONE) { - /* OB is clear exit the loop */ - return 0; - } - - /* wait for 10 usec for OB clear and retry */ - osi_core->osd_ops.udelay(MGBE_MAC_INDIR_AC_OB_WAIT); - count++; - } - - return -1; -} - -/** - * @brief mgbe_mac_indir_addr_write - MAC Indirect AC register write. - * - * Algorithm: writes MAC Indirect AC register - * - * @param[in] base: MGBE virtual base address. - * @param[in] mc_no: MAC AC Mode Select number - * @param[in] addr_offset: MAC AC Address Offset. - * @param[in] value: MAC AC register value - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_mac_indir_addr_write(struct osi_core_priv_data *osi_core, - nveu32_t mc_no, - nveu32_t addr_offset, - nveu32_t value) -{ - void *base = osi_core->base; - nveu32_t addr = 0; - - /* Write MAC_Indir_Access_Data register value */ - osi_writela(osi_core, value, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); - - /* Program MAC_Indir_Access_Ctrl */ - addr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_AC); - - /* update Mode Select */ - addr &= ~(MGBE_MAC_INDIR_AC_MSEL); - addr |= ((mc_no << MGBE_MAC_INDIR_AC_MSEL_SHIFT) & - MGBE_MAC_INDIR_AC_MSEL); - - /* update Address Offset */ - addr &= ~(MGBE_MAC_INDIR_AC_AOFF); - addr |= ((addr_offset << MGBE_MAC_INDIR_AC_AOFF_SHIFT) & - MGBE_MAC_INDIR_AC_AOFF); - - /* Set CMD filed bit 0 for write */ - addr &= ~(MGBE_MAC_INDIR_AC_CMD); - - /* Set OB bit to initiate write */ - addr |= MGBE_MAC_INDIR_AC_OB; - - /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writela(osi_core, addr, (nveu8_t *)base + MGBE_MAC_INDIR_AC); - - /* Wait until OB bit reset */ - if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); - return -1; - } - - return 0; -} - -/** - * @brief mgbe_mac_indir_addr_read - MAC Indirect AC register read. - * - * Algorithm: Reads MAC Indirect AC register - * - * @param[in] base: MGBE virtual base address. - * @param[in] mc_no: MAC AC Mode Select number - * @param[in] addr_offset: MAC AC Address Offset. - * @param[in] value: Pointer MAC AC register value - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_mac_indir_addr_read(struct osi_core_priv_data *osi_core, - nveu32_t mc_no, - nveu32_t addr_offset, - nveu32_t *value) -{ - void *base = osi_core->base; - nveu32_t addr = 0; - - /* Program MAC_Indir_Access_Ctrl */ - addr = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_AC); - - /* update Mode Select */ - addr &= ~(MGBE_MAC_INDIR_AC_MSEL); - addr |= ((mc_no << MGBE_MAC_INDIR_AC_MSEL_SHIFT) & - MGBE_MAC_INDIR_AC_MSEL); - - /* update Address Offset */ - addr &= ~(MGBE_MAC_INDIR_AC_AOFF); - addr |= ((addr_offset << MGBE_MAC_INDIR_AC_AOFF_SHIFT) & - MGBE_MAC_INDIR_AC_AOFF); - - /* Set CMD filed bit to 1 for read */ - addr |= MGBE_MAC_INDIR_AC_CMD; - - /* Set OB bit to initiate write */ - addr |= MGBE_MAC_INDIR_AC_OB; - - /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writela(osi_core, addr, (nveu8_t *)base + MGBE_MAC_INDIR_AC); - - /* Wait until OB bit reset */ - if (mgbe_poll_for_mac_acrtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Fail to write MAC_Indir_Access_Ctrl\n", mc_no); - return -1; - } - - /* Read MAC_Indir_Access_Data register value */ - *value = osi_readla(osi_core, (nveu8_t *)base + MGBE_MAC_INDIR_DATA); - return 0; -} - -/** - * @brief mgbe_config_l2_da_perfect_inverse_match - configure register for - * inverse or perfect match. - * - * Algorithm: This sequence is used to select perfect/inverse matching - * for L2 DA - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] perfect_inverse_match: 1 - inverse mode 0- perfect mode - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void mgbe_config_l2_da_perfect_inverse_match( - struct osi_core_priv_data *osi_core, - unsigned int perfect_inverse_match) -{ - unsigned int value = 0U; - - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); - value &= ~MGBE_MAC_PFR_DAIF; - if (perfect_inverse_match == OSI_INV_MATCH) { - /* Set DA Inverse Filtering */ - value |= MGBE_MAC_PFR_DAIF; - } - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); -} - -/** - * @brief mgbe_config_mac_pkt_filter_reg - configure mac filter register. - * - * Algorithm: This sequence is used to configure MAC in differnet pkt - * processing modes like promiscuous, multicast, unicast, - * hash unicast/multicast. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @note 1) MAC should be initialized and started. see osi_start_mac() - * - * @retval 0 always - */ -static int mgbe_config_mac_pkt_filter_reg(struct osi_core_priv_data *osi_core, - const struct osi_filter *filter) -{ - unsigned int value = 0U; - int ret = 0; - - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); - - /* Retain all other values */ - value &= (MGBE_MAC_PFR_DAIF | MGBE_MAC_PFR_DBF | MGBE_MAC_PFR_SAIF | - MGBE_MAC_PFR_SAF | MGBE_MAC_PFR_PCF | MGBE_MAC_PFR_VTFE | - MGBE_MAC_PFR_IPFE | MGBE_MAC_PFR_DNTU | MGBE_MAC_PFR_RA); - - if ((filter->oper_mode & OSI_OPER_EN_PROMISC) != OSI_DISABLE) { - /* Set Promiscuous Mode Bit */ - value |= MGBE_MAC_PFR_PR; - } - - if ((filter->oper_mode & OSI_OPER_DIS_PROMISC) != OSI_DISABLE) { - /* Reset Promiscuous Mode Bit */ - value &= ~MGBE_MAC_PFR_PR; - } - - if ((filter->oper_mode & OSI_OPER_EN_ALLMULTI) != OSI_DISABLE) { - /* Set Pass All Multicast Bit */ - value |= MGBE_MAC_PFR_PM; - } - - if ((filter->oper_mode & OSI_OPER_DIS_ALLMULTI) != OSI_DISABLE) { - /* Reset Pass All Multicast Bit */ - value &= ~MGBE_MAC_PFR_PM; - } - - if ((filter->oper_mode & OSI_OPER_EN_PERFECT) != OSI_DISABLE) { - /* Set Hash or Perfect Filter Bit */ - value |= MGBE_MAC_PFR_HPF; - } - - if ((filter->oper_mode & OSI_OPER_DIS_PERFECT) != OSI_DISABLE) { - /* Reset Hash or Perfect Filter Bit */ - value &= ~MGBE_MAC_PFR_HPF; - } - - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_PFR); - - if ((filter->oper_mode & OSI_OPER_EN_L2_DA_INV) != OSI_DISABLE) { - mgbe_config_l2_da_perfect_inverse_match(osi_core, - OSI_INV_MATCH); - } - - if ((filter->oper_mode & OSI_OPER_DIS_L2_DA_INV) != OSI_DISABLE) { - mgbe_config_l2_da_perfect_inverse_match(osi_core, - OSI_PFT_MATCH); - } - - return ret; -} - -/** - * @brief mgbe_filter_args_validate - Validates the filter arguments - * - * Algorithm: This function just validates all arguments provided by - * the osi_filter structure variable. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @note 1) MAC should be initialized and stated. see osi_start_mac() - * 2) osi_core->osd should be populated. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_filter_args_validate(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - nveu32_t idx = filter->index; - nveu32_t dma_routing_enable = filter->dma_routing; - nveu32_t dma_chan = filter->dma_chan; - nveu32_t addr_mask = filter->addr_mask; - nveu32_t src_dest = filter->src_dest; - nveu32_t dma_chansel = filter->dma_chansel; - - /* check for valid index (0 to 31) */ - if (idx >= OSI_MGBE_MAX_MAC_ADDRESS_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid MAC filter index\n", - idx); - return -1; - } - - /* check for DMA channel index (0 to 9) */ - if ((dma_chan > OSI_MGBE_MAX_NUM_CHANS - 0x1U) && - (dma_chan != OSI_CHAN_ANY)){ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid dma channel\n", - (nveul64_t)dma_chan); - return -1; - } - - /* validate dma_chansel argument */ - if (dma_chansel > MGBE_MAC_XDCS_DMA_MAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid dma_chansel value\n", - dma_chansel); - return -1; - } - - /* validate addr_mask argument */ - if (addr_mask > MGBE_MAB_ADDRH_MBC_MAX_MASK) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid addr_mask value\n", - addr_mask); - return -1; - } - - /* validate src_dest argument */ - if (src_dest != OSI_SA_MATCH && src_dest != OSI_DA_MATCH) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid src_dest value\n", - src_dest); - return -1; - } - - /* validate dma_routing_enable argument */ - if (dma_routing_enable != OSI_ENABLE && - dma_routing_enable != OSI_DISABLE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid dma_routing value\n", - dma_routing_enable); - return -1; - } - - return 0; -} - -/** - * @brief mgbe_update_mac_addr_low_high_reg- Update L2 address in filter - * register - * - * Algorithm: This routine update MAC address to register for filtering - * based on dma_routing_enable, addr_mask and src_dest. Validation of - * dma_chan as well as DCS bit enabled in RXQ to DMA mapping register - * performed before updating DCS bits. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter: OSI filter structure. - * - * @note 1) MAC should be initialized and stated. see osi_start_mac() - * 2) osi_core->osd should be populated. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_mac_addr_low_high_reg( - struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - nveu32_t idx = filter->index; - nveu32_t dma_chan = filter->dma_chan; - nveu32_t addr_mask = filter->addr_mask; - nveu32_t src_dest = filter->src_dest; - const nveu8_t *addr = filter->mac_address; - nveu32_t dma_chansel = filter->dma_chansel; - nveu32_t xdcs_check; - nveu32_t value = 0x0U; - nve32_t ret = 0; - - /* Validate filter values */ - if (mgbe_filter_args_validate(osi_core, filter) < 0) { - /* Filter argments validation got failed */ - return -1; - } - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_ADDRH((idx))); - - /* read current value at index preserve XDCS current value */ - ret = mgbe_mac_indir_addr_read(osi_core, - MGBE_MAC_DCHSEL, - idx, - &xdcs_check); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "indirect register read failed\n", 0ULL); - return -1; - } - - /* preserve last XDCS bits */ - xdcs_check &= MGBE_MAC_XDCS_DMA_MAX; - - /* High address reset DCS and AE bits and XDCS in MAC_DChSel_IndReg */ - if ((filter->oper_mode & OSI_OPER_ADDR_DEL) != OSI_NONE) { - xdcs_check &= ~OSI_BIT(dma_chan); - ret = mgbe_mac_indir_addr_write(osi_core, MGBE_MAC_DCHSEL, - idx, xdcs_check); - value &= ~(MGBE_MAC_ADDRH_DCS); - - /* XDCS values is always maintained */ - if (xdcs_check == OSI_DISABLE) { - value &= ~(MGBE_MAC_ADDRH_AE); - } - - value |= OSI_MASK_16BITS; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_ADDRH((idx))); - osi_writela(osi_core, OSI_MAX_32BITS, - (unsigned char *)osi_core->base + MGBE_MAC_ADDRL((idx))); - - return 0; - } - - /* Add DMA channel to value in binary */ - value = OSI_NONE; - value |= ((dma_chan << MGBE_MAC_ADDRH_DCS_SHIFT) & - MGBE_MAC_ADDRH_DCS); - - if (idx != 0U) { - /* Add Address mask */ - value |= ((addr_mask << MGBE_MAC_ADDRH_MBC_SHIFT) & - MGBE_MAC_ADDRH_MBC); - - /* Setting Source/Destination Address match valid */ - value |= ((src_dest << MGBE_MAC_ADDRH_SA_SHIFT) & - MGBE_MAC_ADDRH_SA); - } - - osi_writela(osi_core, ((unsigned int)addr[4] | - ((unsigned int)addr[5] << 8) | - MGBE_MAC_ADDRH_AE | - value), - (unsigned char *)osi_core->base + MGBE_MAC_ADDRH((idx))); - - osi_writela(osi_core, ((unsigned int)addr[0] | - ((unsigned int)addr[1] << 8) | - ((unsigned int)addr[2] << 16) | - ((unsigned int)addr[3] << 24)), - (unsigned char *)osi_core->base + MGBE_MAC_ADDRL((idx))); - - /* Write XDCS configuration into MAC_DChSel_IndReg(x) */ - /* Append DCS DMA channel to XDCS hot bit selection */ - xdcs_check |= (OSI_BIT(dma_chan) | dma_chansel); - ret = mgbe_mac_indir_addr_write(osi_core, - MGBE_MAC_DCHSEL, - idx, - xdcs_check); - - return ret; -} - -/** - * @brief mgbe_poll_for_l3l4crtl - Poll for L3_L4 filter register operations. - * - * Algorithm: Waits for waits for transfer busy bit to be cleared in - * L3_L4 address control register to complete filter register operations. - * - * @param[in] addr: MGBE virtual base address. - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_poll_for_l3l4crtl(struct osi_core_priv_data *osi_core) -{ - unsigned int retry = 10; - unsigned int count; - unsigned int l3l4_addr_ctrl = 0; - int cond = 1; - - /* Poll Until L3_L4_Address_Control XB is clear */ - count = 0; - while (cond == 1) { - if (count > retry) { - /* Return error after max retries */ - return -1; - } - - count++; - - l3l4_addr_ctrl = osi_readla(osi_core, - (unsigned char *)osi_core->base + - MGBE_MAC_L3L4_ADDR_CTR); - if ((l3l4_addr_ctrl & MGBE_MAC_L3L4_ADDR_CTR_XB) == OSI_NONE) { - /* Set cond to 0 to exit loop */ - cond = 0; - } else { - /* wait for 10 usec for XB clear */ - osi_core->osd_ops.udelay(MGBE_MAC_XB_WAIT); - } - } - - return 0; -} - -/** - * @brief mgbe_l3l4_filter_write - L3_L4 filter register write. - * - * Algorithm: writes L3_L4 filter register - * - * @param[in] base: MGBE virtual base address. - * @param[in] filter_no: MGBE L3_L4 filter number - * @param[in] filter_type: MGBE L3_L4 filter register type. - * @param[in] value: MGBE L3_L4 filter register value - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_l3l4_filter_write(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int filter_type, - unsigned int value) -{ - void *base = osi_core->base; - unsigned int addr = 0; - - /* Write MAC_L3_L4_Data register value */ - osi_writela(osi_core, value, - (unsigned char *)base + MGBE_MAC_L3L4_DATA); - - /* Program MAC_L3_L4_Address_Control */ - addr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); - - /* update filter number */ - addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); - addr |= ((filter_no << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM_SHIFT) & - MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); - - /* update filter type */ - addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE); - addr |= ((filter_type << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE_SHIFT) & - MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE); - - /* Set TT filed 0 for write */ - addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_TT); - - /* Set XB bit to initiate write */ - addr |= MGBE_MAC_L3L4_ADDR_CTR_XB; - - /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writela(osi_core, addr, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); - - /* Wait untile XB bit reset */ - if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Fail to write L3_L4_Address_Control\n", - filter_type); - return -1; - } - - return 0; -} - -/** - * @brief mgbe_l3l4_filter_read - L3_L4 filter register read. - * - * Algorithm: writes L3_L4 filter register - * - * @param[in] base: MGBE virtual base address. - * @param[in] filter_no: MGBE L3_L4 filter number - * @param[in] filter_type: MGBE L3_L4 filter register type. - * @param[in] *value: Pointer MGBE L3_L4 filter register value - * - * @note MAC needs to be out of reset and proper clock configured. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_l3l4_filter_read(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int filter_type, - unsigned int *value) -{ - void *base = osi_core->base; - unsigned int addr = 0; - - /* Program MAC_L3_L4_Address_Control */ - addr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); - - /* update filter number */ - addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); - addr |= ((filter_no << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM_SHIFT) & - MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM); - - /* update filter type */ - addr &= ~(MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE); - addr |= ((filter_type << MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE_SHIFT) & - MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE); - - /* Set TT field 1 for read */ - addr |= MGBE_MAC_L3L4_ADDR_CTR_TT; - - /* Set XB bit to initiate write */ - addr |= MGBE_MAC_L3L4_ADDR_CTR_XB; - - /* Write MGBE_MAC_L3L4_ADDR_CTR */ - osi_writela(osi_core, addr, - (unsigned char *)base + MGBE_MAC_L3L4_ADDR_CTR); - - /* Wait untile XB bit reset */ - if (mgbe_poll_for_l3l4crtl(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Fail to read L3L4 Address\n", - filter_type); - return -1; - } - - /* Read the MGBE_MAC_L3L4_DATA for filter register data */ - *value = osi_readla(osi_core, - (unsigned char *)base + MGBE_MAC_L3L4_DATA); - return 0; -} - -/** - * @brief mgbe_update_ip4_addr - configure register for IPV4 address filtering - * - * Algorithm: This sequence is used to update IPv4 source/destination - * Address for L3 layer filtering - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] addr: ipv4 address - * @param[in] src_dst_addr_match: 0 - source addr otherwise - dest addr - * - * @note 1) MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_ip4_addr(struct osi_core_priv_data *osi_core, - const unsigned int filter_no, - const unsigned char addr[], - const unsigned int src_dst_addr_match) -{ - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; - - if (addr == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", - 0ULL); - return -1; - } - - if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); - return -1; - } - - /* validate src_dst_addr_match argument */ - if (src_dst_addr_match != OSI_SOURCE_MATCH && - src_dst_addr_match != OSI_INV_MATCH) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid src_dst_addr_match value\n", - src_dst_addr_match); - return -1; - } - - value = addr[3]; - temp = (unsigned int)addr[2] << 8; - value |= temp; - temp = (unsigned int)addr[1] << 16; - value |= temp; - temp = (unsigned int)addr[0] << 24; - value |= temp; - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - ret = mgbe_l3l4_filter_write(osi_core, - filter_no, - MGBE_MAC_L3_AD0R, - value); - } else { - ret = mgbe_l3l4_filter_write(osi_core, - filter_no, - MGBE_MAC_L3_AD1R, - value); - } - - return ret; -} - -/** - * @brief mgbe_update_ip6_addr - add ipv6 address in register - * - * Algorithm: This sequence is used to update IPv6 source/destination - * Address for L3 layer filtering - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] addr: ipv6 adderss - * - * @note 1) MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_ip6_addr(struct osi_core_priv_data *osi_core, - const unsigned int filter_no, - const unsigned short addr[]) -{ - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; - - if (addr == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid address\n", - 0ULL); - return -1; - } - - if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); - return -1; - } - - /* update Bits[31:0] of 128-bit IP addr */ - value = addr[7]; - temp = (unsigned int)addr[6] << 16; - value |= temp; - - ret = mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3_AD0R, value); - if (ret < 0) { - /* Write MGBE_MAC_L3_AD0R fail return error */ - return ret; - } - /* update Bits[63:32] of 128-bit IP addr */ - value = addr[5]; - temp = (unsigned int)addr[4] << 16; - value |= temp; - - ret = mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3_AD1R, value); - if (ret < 0) { - /* Write MGBE_MAC_L3_AD1R fail return error */ - return ret; - } - /* update Bits[95:64] of 128-bit IP addr */ - value = addr[3]; - temp = (unsigned int)addr[2] << 16; - value |= temp; - - ret = mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3_AD2R, value); - if (ret < 0) { - /* Write MGBE_MAC_L3_AD2R fail return error */ - return ret; - } - - /* update Bits[127:96] of 128-bit IP addr */ - value = addr[1]; - temp = (unsigned int)addr[0] << 16; - value |= temp; - - return mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3_AD3R, value); -} - -/** - * @brief mgbe_config_l3_l4_filter_enable - register write to enable L3/L4 - * filters. - * - * Algorithm: This routine to enable/disable L3/l4 filter - * - * @param[in] osi_core: OSI core private data structure. - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_l3_l4_filter_enable( - struct osi_core_priv_data *const osi_core, - unsigned int filter_enb_dis) -{ - unsigned int value = 0U; - void *base = osi_core->base; - - /* validate filter_enb_dis argument */ - if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid filter_enb_dis value\n", - filter_enb_dis); - return -1; - } - - value = osi_readla(osi_core, (unsigned char *)base + MGBE_MAC_PFR); - value &= ~(MGBE_MAC_PFR_IPFE); - value |= ((filter_enb_dis << MGBE_MAC_PFR_IPFE_SHIFT) & - MGBE_MAC_PFR_IPFE); - osi_writela(osi_core, value, (unsigned char *)base + MGBE_MAC_PFR); - - return 0; -} - -/** - * @brief mgbe_update_l4_port_no -program source port no - * - * Algorithm: sequence is used to update Source Port Number for - * L4(TCP/UDP) layer filtering. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] port_no: port number - * @param[in] src_dst_port_match: 0 - source port, otherwise - dest port - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * 3) DCS bits should be enabled in RXQ to DMA mapping register - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_l4_port_no(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned short port_no, - unsigned int src_dst_port_match) -{ - unsigned int value = 0U; - unsigned int temp = 0U; - int ret = 0; - - if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); - return -1; - } - - ret = mgbe_l3l4_filter_read(osi_core, filter_no, - MGBE_MAC_L4_ADDR, &value); - if (ret < 0) { - /* Read MGBE_MAC_L4_ADDR fail return error */ - return ret; - } - - if (src_dst_port_match == OSI_SOURCE_MATCH) { - value &= ~MGBE_MAC_L4_ADDR_SP_MASK; - value |= ((unsigned int)port_no & MGBE_MAC_L4_ADDR_SP_MASK); - } else { - value &= ~MGBE_MAC_L4_ADDR_DP_MASK; - temp = port_no; - value |= ((temp << MGBE_MAC_L4_ADDR_DP_SHIFT) & - MGBE_MAC_L4_ADDR_DP_MASK); - } - - return mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L4_ADDR, value); -} - -/** - * @brief mgbe_set_dcs - check and update dma routing register - * - * Algorithm: Check for request for DCS_enable as well as validate chan - * number and dcs_enable is set. After validation, this sequence is used - * to configure L3((IPv4/IPv6) filters for address matching. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] value: unsigned int value for caller - * @param[in] dma_routing_enable: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter - * - * @note 1) MAC IP should be out of reset and need to be initialized - * as the requirements. - * 2) DCS bit of RxQ should be enabled for dynamic channel selection - * in filter support - * - * @retval updated unsigned int value param - */ -static inline unsigned int mgbe_set_dcs(struct osi_core_priv_data *osi_core, - unsigned int value, - unsigned int dma_routing_enable, - unsigned int dma_chan) -{ - if ((dma_routing_enable == OSI_ENABLE) && (dma_chan < - OSI_MGBE_MAX_NUM_CHANS) && (osi_core->dcs_en == - OSI_ENABLE)) { - value |= ((dma_routing_enable << - MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT) & - MGBE_MAC_L3L4_CTR_DMCHEN0); - value |= ((dma_chan << - MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT) & - MGBE_MAC_L3L4_CTR_DMCHN0); - } - - return value; -} - -/** - * @brief mgbe_helper_l3l4_bitmask - helper function to set L3L4 - * bitmask. - * - * Algorithm: set bit corresponding to L3l4 filter index - * - * @param[in] bitmask: bit mask OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] value: 0 - disable otherwise - l3/l4 filter enabled - * - * @note 1) MAC should be init and started. see osi_start_mac() - */ -static inline void mgbe_helper_l3l4_bitmask(unsigned int *bitmask, - unsigned int filter_no, - unsigned int value) -{ - unsigned int temp; - - temp = OSI_ENABLE; - temp = temp << filter_no; - - /* check against all bit fields for L3L4 filter enable */ - if ((value & MGBE_MAC_L3L4_CTRL_ALL) != OSI_DISABLE) { - /* Set bit mask for index */ - *bitmask |= temp; - } else { - /* Reset bit mask for index */ - *bitmask &= ~temp; - } -} - -/** - * @brief mgbe_config_l3_filters - config L3 filters. - * - * Algorithm: Check for DCS_enable as well as validate channel - * number and if dcs_enable is set. After validation, code flow - * is used to configure L3((IPv4/IPv6) filters resister - * for address matching. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] enb_dis: 1 - enable otherwise - disable L3 filter - * @param[in] ipv4_ipv6_match: 1 - IPv6, otherwise - IPv4 - * @param[in] src_dst_addr_match: 0 - source, otherwise - destination - * @param[in] perfect_inverse_match: normal match(0) or inverse map(1) - * @param[in] dma_routing_enable: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * 3) DCS bit of RxQ should be enabled for dynamic channel selection - * in filter support - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_l3_filters(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int enb_dis, - unsigned int ipv4_ipv6_match, - unsigned int src_dst_addr_match, - unsigned int perfect_inverse_match, - unsigned int dma_routing_enable, - unsigned int dma_chan) -{ - unsigned int value = 0U; - int ret = 0; - - if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); - return -1; - } - /* validate enb_dis argument */ - if (enb_dis != OSI_ENABLE && enb_dis != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid filter_enb_dis value\n", - enb_dis); - return -1; - } - /* validate ipv4_ipv6_match argument */ - if (ipv4_ipv6_match != OSI_IPV6_MATCH && - ipv4_ipv6_match != OSI_IPV4_MATCH) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid ipv4_ipv6_match value\n", - ipv4_ipv6_match); - return -1; - } - /* validate src_dst_addr_match argument */ - if (src_dst_addr_match != OSI_SOURCE_MATCH && - src_dst_addr_match != OSI_INV_MATCH) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid src_dst_addr_match value\n", - src_dst_addr_match); - return -1; - } - /* validate perfect_inverse_match argument */ - if (perfect_inverse_match != OSI_ENABLE && - perfect_inverse_match != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid perfect_inverse_match value\n", - perfect_inverse_match); - return -1; - } - if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > OSI_MGBE_MAX_NUM_CHANS - 1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", - (unsigned long long)dma_chan); - return -1; - } - - ret = mgbe_l3l4_filter_read(osi_core, filter_no, - MGBE_MAC_L3L4_CTR, &value); - if (ret < 0) { - /* MGBE_MAC_L3L4_CTR read fail return here */ - return ret; - } - - value &= ~MGBE_MAC_L3L4_CTR_L3PEN0; - value |= (ipv4_ipv6_match & MGBE_MAC_L3L4_CTR_L3PEN0); - - /* For IPv6 either SA/DA can be checked not both */ - if (ipv4_ipv6_match == OSI_IPV6_MATCH) { - if (enb_dis == OSI_ENABLE) { - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - /* Enable L3 filters for IPv6 SOURCE addr - * matching - */ - value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3SAM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3SAM0 | - MGBE_MAC_L3L4_CTR_L3SAIM0))); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - - } else { - /* Enable L3 filters for IPv6 DESTINATION addr - * matching - */ - value &= ~MGBE_MAC_L3_IP6_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3DAM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3DAM0 | - MGBE_MAC_L3L4_CTR_L3DAIM0))); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - } - } else { - /* Disable L3 filters for IPv6 SOURCE/DESTINATION addr - * matching - */ - value &= ~(MGBE_MAC_L3_IP6_CTRL_CLEAR | - MGBE_MAC_L3L4_CTR_L3PEN0); - } - } else { - if (src_dst_addr_match == OSI_SOURCE_MATCH) { - if (enb_dis == OSI_ENABLE) { - /* Enable L3 filters for IPv4 SOURCE addr - * matching - */ - value &= ~MGBE_MAC_L3_IP4_SA_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3SAM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3SAM0 | - MGBE_MAC_L3L4_CTR_L3SAIM0))); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - } else { - /* Disable L3 filters for IPv4 SOURCE addr - * matching - */ - value &= ~MGBE_MAC_L3_IP4_SA_CTRL_CLEAR; - } - } else { - if (enb_dis == OSI_ENABLE) { - /* Enable L3 filters for IPv4 DESTINATION addr - * matching - */ - value &= ~MGBE_MAC_L3_IP4_DA_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L3DAM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT) & - ((MGBE_MAC_L3L4_CTR_L3DAM0 | - MGBE_MAC_L3L4_CTR_L3DAIM0))); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - } else { - /* Disable L3 filters for IPv4 DESTINATION addr - * matching - */ - value &= ~MGBE_MAC_L3_IP4_DA_CTRL_CLEAR; - } - } - } - - ret = mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3L4_CTR, value); - if (ret < 0) { - /* Write MGBE_MAC_L3L4_CTR fail return error */ - return ret; - } - - /* Set bit corresponding to filter index if value is non-zero */ - mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, - filter_no, value); - - return ret; -} - -/** - * @brief mgbe_config_l4_filters - Config L4 filters. - * - * Algorithm: This sequence is used to configure L4(TCP/UDP) filters for - * SA and DA Port Number matching - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] filter_no: filter index - * @param[in] enb_dis: 1 - enable, otherwise - disable L4 filter - * @param[in] tcp_udp_match: 1 - udp, 0 - tcp - * @param[in] src_dst_port_match: 0 - source port, otherwise - dest port - * @param[in] perfect_inverse_match: normal match(0) or inverse map(1) - * @param[in] dma_routing_enable: filter based dma routing enable(1) - * @param[in] dma_chan: dma channel for routing based on filter - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_l4_filters(struct osi_core_priv_data *osi_core, - unsigned int filter_no, - unsigned int enb_dis, - unsigned int tcp_udp_match, - unsigned int src_dst_port_match, - unsigned int perfect_inverse_match, - unsigned int dma_routing_enable, - unsigned int dma_chan) -{ - unsigned int value = 0U; - int ret = 0; - - if (filter_no >= OSI_MGBE_MAX_L3_L4_FILTER) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "invalid filter index for L3/L4 filter\n", - (unsigned long long)filter_no); - return -1; - } - /* validate enb_dis argument */ - if (enb_dis != OSI_ENABLE && enb_dis != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid filter_enb_dis value\n", - enb_dis); - return -1; - } - /* validate tcp_udp_match argument */ - if (tcp_udp_match != OSI_ENABLE && tcp_udp_match != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid tcp_udp_match value\n", - tcp_udp_match); - return -1; - } - /* validate src_dst_port_match argument */ - if (src_dst_port_match != OSI_SOURCE_MATCH && - src_dst_port_match != OSI_INV_MATCH) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid src_dst_port_match value\n", - src_dst_port_match); - return -1; - } - /* validate perfect_inverse_match argument */ - if (perfect_inverse_match != OSI_ENABLE && - perfect_inverse_match != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid perfect_inverse_match value\n", - perfect_inverse_match); - return -1; - } - if ((dma_routing_enable == OSI_ENABLE) && - (dma_chan > OSI_MGBE_MAX_NUM_CHANS - 1U)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OUTOFBOUND, - "Wrong DMA channel\n", - (unsigned int)dma_chan); - return -1; - } - - ret = mgbe_l3l4_filter_read(osi_core, filter_no, - MGBE_MAC_L3L4_CTR, &value); - if (ret < 0) { - /* MGBE_MAC_L3L4_CTR read fail return here */ - return ret; - } - - value &= ~MGBE_MAC_L3L4_CTR_L4PEN0; - value |= ((tcp_udp_match << 16) & MGBE_MAC_L3L4_CTR_L4PEN0); - - if (src_dst_port_match == OSI_SOURCE_MATCH) { - if (enb_dis == OSI_ENABLE) { - /* Enable L4 filters for SOURCE Port No matching */ - value &= ~MGBE_MAC_L4_SP_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L4SPM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT) & - (MGBE_MAC_L3L4_CTR_L4SPM0 | - MGBE_MAC_L3L4_CTR_L4SPIM0)); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - } else { - /* Disable L4 filters for SOURCE Port No matching */ - value &= ~MGBE_MAC_L4_SP_CTRL_CLEAR; - } - } else { - if (enb_dis == OSI_ENABLE) { - /* Enable L4 filters for DESTINATION port No - * matching - */ - value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR; - value |= ((MGBE_MAC_L3L4_CTR_L4DPM0 | - perfect_inverse_match << - MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT) & - (MGBE_MAC_L3L4_CTR_L4DPM0 | - MGBE_MAC_L3L4_CTR_L4DPIM0)); - value |= mgbe_set_dcs(osi_core, value, - dma_routing_enable, - dma_chan); - } else { - /* Disable L4 filters for DESTINATION port No - * matching - */ - value &= ~MGBE_MAC_L4_DP_CTRL_CLEAR; - } - } - - ret = mgbe_l3l4_filter_write(osi_core, filter_no, - MGBE_MAC_L3L4_CTR, value); - if (ret < 0) { - /* Write MGBE_MAC_L3L4_CTR fail return error */ - return ret; - } - - /* Set bit corresponding to filter index if value is non-zero */ - mgbe_helper_l3l4_bitmask(&osi_core->l3l4_filter_bitmask, - filter_no, value); - - return ret; -} - -/** - * @brief mgbe_config_vlan_filter_reg - config vlan filter register - * - * Algorithm: This sequence is used to enable/disable VLAN filtering and - * also selects VLAN filtering mode- perfect/hash - * - * @param[in] osi_core: Base address from OSI core private data structure. - * @param[in] filter_enb_dis: vlan filter enable/disable - * @param[in] perfect_hash_filtering: perfect or hash filter - * @param[in] perfect_inverse_match: normal or inverse filter - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_vlan_filtering(struct osi_core_priv_data *osi_core, - unsigned int filter_enb_dis, - unsigned int perfect_hash_filtering, - unsigned int perfect_inverse_match) -{ - unsigned int value; - unsigned char *base = osi_core->base; - - /* validate perfect_inverse_match argument */ - if (perfect_hash_filtering == OSI_HASH_FILTER_MODE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "VLAN hash filter is not supported, VTHM not updated\n", - 0ULL); - return -1; - } - if (perfect_hash_filtering != OSI_PERFECT_FILTER_MODE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid perfect_hash_filtering value\n", - perfect_hash_filtering); - return -1; - } - - /* validate filter_enb_dis argument */ - if (filter_enb_dis != OSI_ENABLE && filter_enb_dis != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid filter_enb_dis value\n", - filter_enb_dis); - return -1; - } - - /* validate perfect_inverse_match argument */ - if (perfect_inverse_match != OSI_ENABLE && - perfect_inverse_match != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid perfect_inverse_match value\n", - perfect_inverse_match); - return -1; - } - - /* Read MAC PFR value set VTFE bit */ - value = osi_readla(osi_core, base + MGBE_MAC_PFR); - value &= ~(MGBE_MAC_PFR_VTFE); - value |= ((filter_enb_dis << MGBE_MAC_PFR_VTFE_SHIFT) & - MGBE_MAC_PFR_VTFE); - osi_writela(osi_core, value, base + MGBE_MAC_PFR); - - /* Read MAC VLAN TR register value set VTIM bit */ - value = osi_readla(osi_core, base + MGBE_MAC_VLAN_TR); - value &= ~(MGBE_MAC_VLAN_TR_VTIM | MGBE_MAC_VLAN_TR_VTHM); - value |= ((perfect_inverse_match << MGBE_MAC_VLAN_TR_VTIM_SHIFT) & - MGBE_MAC_VLAN_TR_VTIM); - osi_writela(osi_core, value, base + MGBE_MAC_VLAN_TR); - - return 0; -} - -/** - * @brief mgbe_config_ptp_rxq - Config PTP RX packets queue route - * - * Algorithm: This function is used to program the PTP RX packets queue. - * - * @param[in] osi_core: OSI core private data. - * @param[in] rxq_idx: PTP RXQ index. - * @param[in] enable: PTP RXQ route enable(1) or disable(0). - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_ptp_rxq(struct osi_core_priv_data *const osi_core, - const unsigned int rxq_idx, - const unsigned int enable) -{ - unsigned char *base = osi_core->base; - unsigned int value = 0U; - unsigned int i = 0U; - - /* Validate the RX queue index argument */ - if (rxq_idx >= OSI_MGBE_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid PTP RX queue index\n", - rxq_idx); - return -1; - } - - /* Validate enable argument */ - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid enable input\n", - enable); - return -1; - } - - /* Validate PTP RX queue enable */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - if (osi_core->mtl_queues[i] == rxq_idx) { - /* Given PTP RX queue is enabled */ - break; - } - } - if (i == osi_core->num_mtl_queues) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "PTP RX queue not enabled\n", - rxq_idx); - return -1; - } - - /* Read MAC_RxQ_Ctrl1 */ - value = osi_readla(osi_core, base + MGBE_MAC_RQC1R); - /* Check for enable or disable */ - if (enable == OSI_DISABLE) { - /** Reset OMCBCQ bit to disable over-riding the MCBC Queue - * priority for the PTP RX queue. - **/ - value &= ~MGBE_MAC_RQC1R_OMCBCQ; - } else { - /* Store PTP RX queue into OSI private data */ - osi_core->ptp_config.ptp_rx_queue = rxq_idx; - /* Program PTPQ with ptp_rxq */ - value &= ~MGBE_MAC_RQC1R_PTPQ; - value |= (rxq_idx << MGBE_MAC_RQC1R_PTPQ_SHIFT); - /** Set TPQC to 0x1 for VLAN Tagged PTP over - * ethernet packets are routed to Rx Queue specified - * by PTPQ field - **/ - value |= MGBE_MAC_RQC1R_TPQC0; - /** Set OMCBCQ bit to enable over-riding the MCBC Queue - * priority for the PTP RX queue. - **/ - value |= MGBE_MAC_RQC1R_OMCBCQ; - } - /* Write MAC_RxQ_Ctrl1 */ - osi_writela(osi_core, value, base + MGBE_MAC_RQC1R); - - return 0; -} - -/** - * @brief mgbe_flush_mtl_tx_queue - Flush MTL Tx queue - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] qinx: MTL queue index. - * - * @note 1) MAC should out of reset and clocks enabled. - * 2) hw core initialized. see osi_hw_core_init(). - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_flush_mtl_tx_queue( - struct osi_core_priv_data *const osi_core, - const nveu32_t qinx) -{ - void *addr = osi_core->base; - nveu32_t retry = 1000; - nveu32_t count; - nveu32_t value; - nve32_t cond = 1; - - if (qinx >= OSI_MGBE_MAX_NUM_QUEUES) { - return -1; - } - - /* Read Tx Q Operating Mode Register and flush TxQ */ - value = osi_readla(osi_core, (nveu8_t *)addr + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - value |= MGBE_MTL_QTOMR_FTQ; - osi_writela(osi_core, value, (nveu8_t *)addr + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - - /* Poll Until FTQ bit resets for Successful Tx Q flush */ - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - - value = osi_readla(osi_core, (nveu8_t *)addr + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - if ((value & MGBE_MTL_QTOMR_FTQ_LPOS) == OSI_NONE) { - cond = 0; - } else { - osi_core->osd_ops.msleep(1); - } - } - - return 0; -} - -/** - * @brief mgbe_config_mac_loopback - Configure MAC to support loopback - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] lb_mode: Enable or Disable MAC loopback mode - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_mac_loopback(struct osi_core_priv_data *const osi_core, - unsigned int lb_mode) -{ - unsigned int value; - void *addr = osi_core->base; - - /* don't allow only if loopback mode is other than 0 or 1 */ - if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { - return -1; - } - - /* Read MAC Configuration Register */ - value = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); - if (lb_mode == OSI_ENABLE) { - /* Enable Loopback Mode */ - value |= MGBE_MAC_RMCR_LM; - } else { - value &= ~MGBE_MAC_RMCR_LM; - } - - osi_writela(osi_core, value, (unsigned char *)addr + MGBE_MAC_RMCR); - - return 0; -} - -/** - * @brief mgbe_config_arp_offload - Enable/Disable ARP offload - * - * Algorithm: - * 1) Read the MAC configuration register - * 2) If ARP offload is to be enabled, program the IP address in - * ARPPA register - * 3) Enable/disable the ARPEN bit in MCR and write back to the MCR. - * - * @param[in] addr: MGBE virtual base address. - * @param[in] enable: Flag variable to enable/disable ARP offload - * @param[in] ip_addr: IP address of device to be programmed in HW. - * HW will use this IP address to respond to ARP requests. - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) Valid 4 byte IP address as argument ip_addr - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_arp_offload(struct osi_core_priv_data *const osi_core, - const unsigned int enable, - const unsigned char *ip_addr) -{ - unsigned int mac_rmcr; - unsigned int val; - void *addr = osi_core->base; - - if (enable != OSI_ENABLE && enable != OSI_DISABLE) { - return -1; - } - - mac_rmcr = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); - - if (enable == OSI_ENABLE) { - val = (((unsigned int)ip_addr[0]) << 24) | - (((unsigned int)ip_addr[1]) << 16) | - (((unsigned int)ip_addr[2]) << 8) | - (((unsigned int)ip_addr[3])); - - osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_ARPPA); - - mac_rmcr |= MGBE_MAC_RMCR_ARPEN; - } else { - mac_rmcr &= ~MGBE_MAC_RMCR_ARPEN; - } - - osi_writela(osi_core, mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); - - return 0; -} - -/** - * @brief mgbe_config_rxcsum_offload - Enable/Disale rx checksum offload in HW - * - * Algorithm: - * 1) Read the MAC configuration register. - * 2) Enable the IP checksum offload engine COE in MAC receiver. - * 3) Update the MAC configuration register. - * - * @param[in] addr: MGBE virtual base address. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_rxcsum_offload( - struct osi_core_priv_data *const osi_core, - unsigned int enabled) -{ - void *addr = osi_core->base; - unsigned int mac_rmcr; - - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { - return -1; - } - - mac_rmcr = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_RMCR); - if (enabled == OSI_ENABLE) { - mac_rmcr |= MGBE_MAC_RMCR_IPC; - } else { - mac_rmcr &= ~MGBE_MAC_RMCR_IPC; - } - - osi_writela(osi_core, mac_rmcr, (unsigned char *)addr + MGBE_MAC_RMCR); - - return 0; -} - -/** - * @brief mgbe_config_frp - Enable/Disale RX Flexible Receive Parser in HW - * - * Algorithm: - * 1) Read the MTL OP Mode configuration register. - * 2) Enable/Disable FRPE bit based on the input. - * 3) Write the MTL OP Mode configuration register. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_frp(struct osi_core_priv_data *const osi_core, - const unsigned int enabled) -{ - unsigned char *base = osi_core->base; - unsigned int op_mode = 0U, val = 0U; - int ret = -1; - - if (enabled != OSI_ENABLE && enabled != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid enable input\n", - enabled); - return -1; - } - - op_mode = osi_readla(osi_core, base + MGBE_MTL_OP_MODE); - if (enabled == OSI_ENABLE) { - /* Set FRPE bit of MTL_Operation_Mode register */ - op_mode |= MGBE_MTL_OP_MODE_FRPE; - osi_writela(osi_core, op_mode, base + MGBE_MTL_OP_MODE); - - /* Verify RXPI bit set in MTL_RXP_Control_Status */ - ret = osi_readl_poll_timeout((base + MGBE_MTL_RXP_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & MGBE_MTL_RXP_CS_RXPI) == - MGBE_MTL_RXP_CS_RXPI), - (MGBE_MTL_FRP_READ_UDELAY), - (MGBE_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to enable FRP\n", - val); - return -1; - } - - /* Enable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readla(osi_core, base + MGBE_MTL_RXP_INTR_CS); - val |= (MGBE_MTL_RXP_INTR_CS_NVEOVIE | - MGBE_MTL_RXP_INTR_CS_NPEOVIE | - MGBE_MTL_RXP_INTR_CS_FOOVIE | - MGBE_MTL_RXP_INTR_CS_PDRFIE); - osi_writela(osi_core, val, base + MGBE_MTL_RXP_INTR_CS); - } else { - /* Reset FRPE bit of MTL_Operation_Mode register */ - op_mode &= ~MGBE_MTL_OP_MODE_FRPE; - osi_writela(osi_core, op_mode, base + MGBE_MTL_OP_MODE); - - /* Verify RXPI bit reset in MTL_RXP_Control_Status */ - ret = osi_readl_poll_timeout((base + MGBE_MTL_RXP_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & MGBE_MTL_RXP_CS_RXPI) == - OSI_NONE), - (MGBE_MTL_FRP_READ_UDELAY), - (MGBE_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to disable FRP\n", - val); - return -1; - } - - /* Disable FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readla(osi_core, base + MGBE_MTL_RXP_INTR_CS); - val &= ~(MGBE_MTL_RXP_INTR_CS_NVEOVIE | - MGBE_MTL_RXP_INTR_CS_NPEOVIE | - MGBE_MTL_RXP_INTR_CS_FOOVIE | - MGBE_MTL_RXP_INTR_CS_PDRFIE); - osi_writela(osi_core, val, base + MGBE_MTL_RXP_INTR_CS); - } - - return 0; -} - -/** - * @brief mgbe_frp_write - Write FRP entry into HW - * - * Algorithm: This function will write FRP entry registers into HW. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] acc_sel: FRP Indirect Access Selection. - * 0x0 : Access FRP Instruction Table. - * 0x1 : Access Indirect FRP Register block. - * @param[in] addr: FRP register address. - * @param[in] data: FRP register data. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_frp_write(struct osi_core_priv_data *osi_core, - unsigned int acc_sel, - unsigned int addr, - unsigned int data) -{ - int ret = 0; - unsigned char *base = osi_core->base; - unsigned int val = 0U; - - if (acc_sel != OSI_ENABLE && acc_sel != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid acc_sel argment\n", - acc_sel); - return -1; - } - - /* Wait for ready */ - ret = osi_readl_poll_timeout((base + MGBE_MTL_RXP_IND_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & MGBE_MTL_RXP_IND_CS_BUSY) == - OSI_NONE), - (MGBE_MTL_FRP_READ_UDELAY), - (MGBE_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to write\n", - val); - return -1; - } - - /* Write data into MTL_RXP_Indirect_Acc_Data */ - osi_writela(osi_core, data, base + MGBE_MTL_RXP_IND_DATA); - - /* Program MTL_RXP_Indirect_Acc_Control_Status */ - val = osi_readla(osi_core, base + MGBE_MTL_RXP_IND_CS); - /* Set/Reset ACCSEL for FRP Register block/Instruction Table */ - if (acc_sel == OSI_ENABLE) { - /* Set ACCSEL bit */ - val |= MGBE_MTL_RXP_IND_CS_ACCSEL; - } else { - /* Reset ACCSEL bit */ - val &= ~MGBE_MTL_RXP_IND_CS_ACCSEL; - } - /* Set WRRDN for write */ - val |= MGBE_MTL_RXP_IND_CS_WRRDN; - /* Clear and add ADDR */ - val &= ~MGBE_MTL_RXP_IND_CS_ADDR; - val |= (addr & MGBE_MTL_RXP_IND_CS_ADDR); - /* Start write */ - val |= MGBE_MTL_RXP_IND_CS_BUSY; - osi_writela(osi_core, val, base + MGBE_MTL_RXP_IND_CS); - - /* Wait for complete */ - ret = osi_readl_poll_timeout((base + MGBE_MTL_RXP_IND_CS), - (osi_core->osd_ops.udelay), - (val), - ((val & MGBE_MTL_RXP_IND_CS_BUSY) == - OSI_NONE), - (MGBE_MTL_FRP_READ_UDELAY), - (MGBE_MTL_FRP_READ_RETRY)); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Fail to write\n", - val); - return -1; - } - - return ret; -} - -/** - * @brief mgbe_update_frp_entry - Update FRP Instruction Table entry in HW - * - * Algorithm: - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] pos: FRP Instruction Table entry location. - * @param[in] data: FRP entry data structure. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_frp_entry(struct osi_core_priv_data *const osi_core, - const unsigned int pos, - struct osi_core_frp_data *const data) -{ - unsigned int val = 0U, tmp = 0U; - int ret = -1; - - /* Validate pos value */ - if (pos >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid FRP table entry\n", - pos); - return -1; - } - - /** Write Match Data into IE0 **/ - val = data->match_data; - ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE0(pos), val); - if (ret < 0) { - /* Match Data Write fail */ - return -1; - } - - /** Write Match Enable into IE1 **/ - val = data->match_en; - ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE1(pos), val); - if (ret < 0) { - /* Match Enable Write fail */ - return -1; - } - - /** Write AF, RF, IM, NIC, FO and OKI into IE2 **/ - val = 0; - if (data->accept_frame == OSI_ENABLE) { - /* Set AF Bit */ - val |= MGBE_MTL_FRP_IE2_AF; - } - if (data->reject_frame == OSI_ENABLE) { - /* Set RF Bit */ - val |= MGBE_MTL_FRP_IE2_RF; - } - if (data->inverse_match == OSI_ENABLE) { - /* Set IM Bit */ - val |= MGBE_MTL_FRP_IE2_IM; - } - if (data->next_ins_ctrl == OSI_ENABLE) { - /* Set NIC Bit */ - val |= MGBE_MTL_FRP_IE2_NC; - } - tmp = data->frame_offset; - val |= ((tmp << MGBE_MTL_FRP_IE2_FO_SHIFT) & MGBE_MTL_FRP_IE2_FO); - tmp = data->ok_index; - val |= ((tmp << MGBE_MTL_FRP_IE2_OKI_SHIFT) & MGBE_MTL_FRP_IE2_OKI); - tmp = data->dma_chsel; - val |= ((tmp << MGBE_MTL_FRP_IE2_DCH_SHIFT) & MGBE_MTL_FRP_IE2_DCH); - ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE2(pos), val); - if (ret < 0) { - /* FRP IE2 Write fail */ - return -1; - } - - /** Write DCH into IE3 **/ - val = (data->dma_chsel & MGBE_MTL_FRP_IE3_DCH_MASK); - ret = mgbe_frp_write(osi_core, OSI_DISABLE, MGBE_MTL_FRP_IE3(pos), val); - if (ret < 0) { - /* DCH Write fail */ - return -1; - } - - return ret; -} - -/** - * @brief mgbe_update_frp_nve - Update FRP NVE into HW - * - * Algorithm: - * - * @param[in] addr: MGBE virtual base address. - * @param[in] enabled: Flag to indicate feature is to be enabled/disabled. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_update_frp_nve(struct osi_core_priv_data *const osi_core, - const unsigned int nve) -{ - unsigned int val; - unsigned char *base = osi_core->base; - - /* Validate the NVE value */ - if (nve >= OSI_FRP_MAX_ENTRY) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid NVE value\n", - nve); - return -1; - } - - /* Update NVE and NPE in MTL_RXP_Control_Status register */ - val = osi_readla(osi_core, base + MGBE_MTL_RXP_CS); - /* Clear old NVE and NPE */ - val &= ~(MGBE_MTL_RXP_CS_NVE | MGBE_MTL_RXP_CS_NPE); - /* Add new NVE and NPE */ - val |= (nve & MGBE_MTL_RXP_CS_NVE); - val |= ((nve << MGBE_MTL_RXP_CS_NPE_SHIFT) & MGBE_MTL_RXP_CS_NPE); - osi_writela(osi_core, val, base + MGBE_MTL_RXP_CS); - - return 0; -} - -/** - * @brief update_rfa_rfd - Update RFD and RSA values - * - * Algorithm: Calulates and stores the RSD (Threshold for Dectivating - * Flow control) and RSA (Threshold for Activating Flow Control) values - * based on the Rx FIFO size - * - * @param[in] rx_fifo: Rx FIFO size. - * @param[in] value: Stores RFD and RSA values - */ -static void update_rfa_rfd(unsigned int rx_fifo, unsigned int *value) -{ - switch (rx_fifo) { - case MGBE_21K: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_18_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case MGBE_24K: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_21_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case MGBE_27K: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_24_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case MGBE_32K: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_29_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case MGBE_38K: - case MGBE_48K: - case MGBE_64K: - case MGBE_96K: - case MGBE_192K: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_32_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - case MGBE_19K: - default: - /* Update RFD */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - *value |= (FULL_MINUS_4_K << - MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFD_MASK; - /* Update RFA */ - *value &= ~MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - *value |= (FULL_MINUS_16_K << - MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT) & - MGBE_MTL_RXQ_OP_MODE_RFA_MASK; - break; - } -} - -/** - * @brief mgbe_configure_mtl_queue - Configure MTL Queue - * - * Algorithm: This takes care of configuring the below - * parameters for the MTL Queue - * 1) Mapping MTL Rx queue and DMA Rx channel - * 2) Flush TxQ - * 3) Enable Store and Forward mode for Tx, Rx - * 4) Configure Tx and Rx MTL Queue sizes - * 5) Configure TxQ weight - * 6) Enable Rx Queues - * 7) Enable TX Underflow Interrupt for MTL Q - * - * @param[in] qinx: Queue number that need to be configured. - * @param[in] osi_core: OSI core private data. - * @param[in] tx_fifo: MTL TX queue size for a MTL queue. - * @param[in] rx_fifo: MTL RX queue size for a MTL queue. - * - * @note MAC has to be out of reset. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_configure_mtl_queue(nveu32_t qinx, - struct osi_core_priv_data *osi_core, - nveu32_t tx_fifo, - nveu32_t rx_fifo) -{ - nveu32_t value = 0; - nve32_t ret = 0; - - /* Program ETSALG (802.1Qaz) and RAA in MTL_Operation_Mode - * register to initialize the MTL operation in case - * of multiple Tx and Rx queues default : ETSALG WRR RAA SP - */ - - /* Program the priorities mapped to the Selected Traffic - * Classes in MTL_TC_Prty_Map0-3 registers. This register is - * to tell traffic class x should be blocked from transmitting - * for the specified pause time when a PFC packet is received - * with priorities matching the priorities programmed in this field - * default: 0x0 - */ - - /* Program the Transmit Selection Algorithm (TSA) in - * MTL_TC[n]_ETS_Control register for all the Selected - * Traffic Classes (n=0, 1, …, Max selected number of TCs - 1) - * Setting related to CBS will come here for TC. - * default: 0x0 SP - */ - ret = mgbe_flush_mtl_tx_queue(osi_core, qinx); - if (ret < 0) { - return ret; - } - - value = (tx_fifo << MGBE_MTL_TXQ_SIZE_SHIFT); - /* Enable Store and Forward mode */ - value |= MGBE_MTL_TSF; - /*TTC not applicable for TX*/ - /* Enable TxQ */ - value |= MGBE_MTL_TXQEN; - value |= (osi_core->tc[qinx] << MGBE_MTL_CHX_TX_OP_MODE_Q2TC_SH); - osi_writela(osi_core, value, (unsigned char *) - osi_core->base + MGBE_MTL_CHX_TX_OP_MODE(qinx)); - - /* read RX Q0 Operating Mode Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_CHX_RX_OP_MODE(qinx)); - value |= (rx_fifo << MGBE_MTL_RXQ_SIZE_SHIFT); - /* Enable Store and Forward mode */ - value |= MGBE_MTL_RSF; - /* Enable HW flow control */ - value |= MGBE_MTL_RXQ_OP_MODE_EHFC; - - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MTL_CHX_RX_OP_MODE(qinx)); - - /* Update RFA and RFD - * RFA: Threshold for Activating Flow Control - * RFD: Threshold for Deactivating Flow Control - */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_RXQ_FLOW_CTRL(qinx)); - update_rfa_rfd(rx_fifo, &value); - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_RXQ_FLOW_CTRL(qinx)); - - /* Transmit Queue weight */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_TCQ_QW(qinx)); - value |= (MGBE_MTL_TCQ_QW_ISCQW + qinx); - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MTL_TCQ_QW(qinx)); - /* Enable Rx Queue Control */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_RQC0R); - value |= ((osi_core->rxq_ctrl[qinx] & MGBE_MAC_RXQC0_RXQEN_MASK) << - (MGBE_MAC_RXQC0_RXQEN_SHIFT(qinx))); - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_RQC0R); - - /* Enable TX Underflow Interrupt for MTL Q */ - value = osi_readl((unsigned char *)osi_core->base + - MGBE_MTL_QINT_ENABLE(qinx)); - value |= MGBE_MTL_QINT_TXUIE; - osi_writel(value, (unsigned char *)osi_core->base + - MGBE_MTL_QINT_ENABLE(qinx)); - return 0; -} - -/** - * @brief mgbe_rss_write_reg - Write into RSS registers - * - * Algorithm: Programes RSS hash table or RSS hash key. - * - * @param[in] addr: MAC base address - * @param[in] idx: Hash table or key index - * @param[in] value: Value to be programmed in RSS data register. - * @param[in] is_key: To represent passed value key or table data. - * - * @note MAC has to be out of reset. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_rss_write_reg(struct osi_core_priv_data *osi_core, - unsigned int idx, - unsigned int value, - unsigned int is_key) -{ - unsigned char *addr = (unsigned char *)osi_core->base; - unsigned int retry = 100; - unsigned int ctrl = 0; - unsigned int count = 0; - int cond = 1; - - /* data into RSS Lookup Table or RSS Hash Key */ - osi_writela(osi_core, value, addr + MGBE_MAC_RSS_DATA); - - if (is_key == OSI_ENABLE) { - ctrl |= MGBE_MAC_RSS_ADDR_ADDRT; - } - - ctrl |= idx << MGBE_MAC_RSS_ADDR_RSSIA_SHIFT; - ctrl |= MGBE_MAC_RSS_ADDR_OB; - ctrl &= ~MGBE_MAC_RSS_ADDR_CT; - osi_writela(osi_core, ctrl, addr + MGBE_MAC_RSS_ADDR); - - /* poll for write operation to complete */ - while (cond == 1) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Failed to update RSS Hash key or table\n", - 0ULL); - return -1; - } - - count++; - - value = osi_readla(osi_core, addr + MGBE_MAC_RSS_ADDR); - if ((value & MGBE_MAC_RSS_ADDR_OB) == OSI_NONE) { - cond = 0; - } else { - osi_core->osd_ops.udelay(100); - } - } - - return 0; -} - -/** - * @brief mgbe_config_rss - Configure RSS - * - * Algorithm: Programes RSS hash table or RSS hash key. - * - * @param[in] osi_core: OSI core private data. - * - * @note MAC has to be out of reset. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_rss(struct osi_core_priv_data *osi_core) -{ - unsigned char *addr = (unsigned char *)osi_core->base; - unsigned int value = 0; - unsigned int i = 0, j = 0; - int ret = 0; - - if (osi_core->rss.enable == OSI_DISABLE) { - /* RSS not supported */ - return 0; - } - - /* No need to enable RSS for single Queue */ - if (osi_core->num_mtl_queues == 1U) { - return 0; - } - - /* Program the hash key */ - for (i = 0; i < OSI_RSS_HASH_KEY_SIZE; i += 4U) { - value = ((unsigned int)osi_core->rss.key[i] | - (unsigned int)osi_core->rss.key[i + 1U] << 8U | - (unsigned int)osi_core->rss.key[i + 2U] << 16U | - (unsigned int)osi_core->rss.key[i + 3U] << 24U); - ret = mgbe_rss_write_reg(osi_core, j, value, OSI_ENABLE); - if (ret < 0) { - return ret; - } - j++; - } - - /* Program Hash table */ - for (i = 0; i < OSI_RSS_MAX_TABLE_SIZE; i++) { - ret = mgbe_rss_write_reg(osi_core, i, osi_core->rss.table[i], - OSI_NONE); - if (ret < 0) { - return ret; - } - } - - /* Enable RSS */ - value = osi_readla(osi_core, addr + MGBE_MAC_RSS_CTRL); - value |= MGBE_MAC_RSS_CTRL_UDP4TE | MGBE_MAC_RSS_CTRL_TCP4TE | - MGBE_MAC_RSS_CTRL_IP2TE | MGBE_MAC_RSS_CTRL_RSSE; - osi_writela(osi_core, value, addr + MGBE_MAC_RSS_CTRL); - - return 0; -} - -/** - * @brief mgbe_config_flow_control - Configure MAC flow control settings - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flw_ctrl: flw_ctrl settings - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_flow_control(struct osi_core_priv_data *const osi_core, - const nveu32_t flw_ctrl) -{ - unsigned int val; - void *addr = osi_core->base; - - /* return on invalid argument */ - if (flw_ctrl > (OSI_FLOW_CTRL_RX | OSI_FLOW_CTRL_TX)) { - return -1; - } - - /* Configure MAC Tx Flow control */ - /* Read MAC Tx Flow control Register of Q0 */ - val = osi_readla(osi_core, - (unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); - - /* flw_ctrl BIT0: 1 is for tx flow ctrl enable - * flw_ctrl BIT0: 0 is for tx flow ctrl disable - */ - if ((flw_ctrl & OSI_FLOW_CTRL_TX) == OSI_FLOW_CTRL_TX) { - /* Enable Tx Flow Control */ - val |= MGBE_MAC_QX_TX_FLW_CTRL_TFE; - /* Mask and set Pause Time */ - val &= ~MGBE_MAC_PAUSE_TIME_MASK; - val |= MGBE_MAC_PAUSE_TIME & MGBE_MAC_PAUSE_TIME_MASK; - } else { - /* Disable Tx Flow Control */ - val &= ~MGBE_MAC_QX_TX_FLW_CTRL_TFE; - } - - /* Write to MAC Tx Flow control Register of Q0 */ - osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_QX_TX_FLW_CTRL(0U)); - - /* Configure MAC Rx Flow control*/ - /* Read MAC Rx Flow control Register */ - val = osi_readla(osi_core, - (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); - - /* flw_ctrl BIT1: 1 is for rx flow ctrl enable - * flw_ctrl BIT1: 0 is for rx flow ctrl disable - */ - if ((flw_ctrl & OSI_FLOW_CTRL_RX) == OSI_FLOW_CTRL_RX) { - /* Enable Rx Flow Control */ - val |= MGBE_MAC_RX_FLW_CTRL_RFE; - } else { - /* Disable Rx Flow Control */ - val &= ~MGBE_MAC_RX_FLW_CTRL_RFE; - } - - /* Write to MAC Rx Flow control Register */ - osi_writela(osi_core, val, - (unsigned char *)addr + MGBE_MAC_RX_FLW_CTRL); - - return 0; -} - -#ifdef HSI_SUPPORT -/** - * @brief mgbe_hsi_configure - Configure HSI - * - * Algorithm: enable LIC interrupt and HSI features - * - * @param[in, out] osi_core: OSI core private data structure. - * @param[in] enable: OSI_ENABLE for Enabling HSI feature, else disable - * - * @retval 0 on success - * @retval -1 on failure - */ -static int mgbe_hsi_configure(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value = 0U; - int ret = 0; - - if (enable == OSI_ENABLE) { - osi_core->hsi.enabled = OSI_ENABLE; - osi_core->hsi.reporter_id = hsi_err_code[osi_core->instance_id][REPORTER_IDX]; - - /* T23X-MGBE_HSIv2-10 Enable PCS ECC */ - value = (EN_ERR_IND | FEC_EN); - ret = xpcs_write_safety(osi_core, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, value); - if (ret != 0) { - return ret; - } - /* T23X-MGBE_HSIv2-12:Initialization of Transaction Timeout in PCS */ - /* T23X-MGBE_HSIv2-11:Initialization of Watchdog Timer */ - value = (0xCCU << XPCS_SFTY_1US_MULT_SHIFT) & XPCS_SFTY_1US_MULT_MASK; - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, value); - if (ret != 0) { - return ret; - } - /* T23X-MGBE_HSIv2-1 Configure ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_CONTROL); - value &= ~MGBE_MTL_ECC_MTXED; - value &= ~MGBE_MTL_ECC_MRXED; - value &= ~MGBE_MTL_ECC_MGCLED; - value &= ~MGBE_MTL_ECC_MRXPED; - value &= ~MGBE_MTL_ECC_TSOED; - value &= ~MGBE_MTL_ECC_DESCED; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_CONTROL); - - /* T23X-MGBE_HSIv2-5: Enabling and Initialization of Transaction Timeout */ - value = (0x198U << MGBE_TMR_SHIFT) & MGBE_TMR_MASK; - value |= (0x0U << MGBE_CTMR_SHIFT) & MGBE_CTMR_MASK; - value |= (0x2U << MGBE_LTMRMD_SHIFT) & MGBE_LTMRMD_MASK; - value |= (0x1U << MGBE_NTMRMD_SHIFT) & MGBE_NTMRMD_MASK; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_DWCXG_CORE_MAC_FSM_ACT_TIMER); - - /* T23X-MGBE_HSIv2-3: Enabling and Initialization of Watchdog Timer */ - /* T23X-MGBE_HSIv2-4: Enabling of Consistency Monitor for XGMAC FSM State */ - // TODO: enable MGBE_TMOUTEN. - value = MGBE_PRTYEN; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MAC_FSM_CONTROL); - - /* T23X-MGBE_HSIv2-2: Enabling of Bus Parity */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_DPP_CONTROL); - value &= ~MGBE_DDPP; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MTL_DPP_CONTROL); - - /* T23X-MGBE_HSIv2-38: Initialization of Register Parity for control registers */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MAC_SCSR_CONTROL); - value |= MGBE_CPEN; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MAC_SCSR_CONTROL); - - /* Enable Interrupt */ - /* T23X-MGBE_HSIv2-1: Enabling of Memory ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_INTERRUPT_ENABLE); - value |= MGBE_MTL_TXCEIE; - value |= MGBE_MTL_RXCEIE; - value |= MGBE_MTL_GCEIE; - value |= MGBE_MTL_RPCEIE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_DMA_ECC_INTERRUPT_ENABLE); - value |= MGBE_DMA_TCEIE; - value |= MGBE_DMA_DCEIE; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_DMA_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - value |= MGBE_REGISTER_PARITY_ERR; - value |= MGBE_CORE_CORRECTABLE_ERR; - value |= MGBE_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - value |= XPCS_CORE_CORRECTABLE_ERR; - value |= XPCS_CORE_UNCORRECTABLE_ERR; - value |= XPCS_REGISTER_PARITY_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - } else { - osi_core->hsi.enabled = OSI_DISABLE; - - /* T23X-MGBE_HSIv2-10 Disable PCS ECC */ - ret = xpcs_write_safety(osi_core, XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL, 0); - if (ret != 0) { - return ret; - } - /* T23X-MGBE_HSIv2-11:Deinitialization of Watchdog Timer */ - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_SFTY_TMR_CTRL, 0); - if (ret != 0) { - return ret; - } - /* T23X-MGBE_HSIv2-1 Disable ECC */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_CONTROL); - value |= MGBE_MTL_ECC_MTXED; - value |= MGBE_MTL_ECC_MRXED; - value |= MGBE_MTL_ECC_MGCLED; - value |= MGBE_MTL_ECC_MRXPED; - value |= MGBE_MTL_ECC_TSOED; - value |= MGBE_MTL_ECC_DESCED; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_CONTROL); - - /* T23X-MGBE_HSIv2-5: Enabling and Initialization of Transaction Timeout */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + MGBE_DWCXG_CORE_MAC_FSM_ACT_TIMER); - - /* T23X-MGBE_HSIv2-4: Enabling of Consistency Monitor for XGMAC FSM State */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + MGBE_MAC_FSM_CONTROL); - - /* T23X-MGBE_HSIv2-2: Disable of Bus Parity */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_DPP_CONTROL); - value |= MGBE_DDPP; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MTL_DPP_CONTROL); - - /* T23X-MGBE_HSIv2-38: Disable Register Parity for control registers */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MAC_SCSR_CONTROL); - value &= ~MGBE_CPEN; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MAC_SCSR_CONTROL); - - /* Disable Interrupts */ - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + MGBE_MTL_ECC_INTERRUPT_ENABLE); - - osi_writela(osi_core, 0, - (nveu8_t *)osi_core->base + MGBE_DMA_ECC_INTERRUPT_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - value &= ~MGBE_REGISTER_PARITY_ERR; - value &= ~MGBE_CORE_CORRECTABLE_ERR; - value &= ~MGBE_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - value &= ~XPCS_CORE_CORRECTABLE_ERR; - value &= ~XPCS_CORE_UNCORRECTABLE_ERR; - value &= ~XPCS_REGISTER_PARITY_ERR; - osi_writela(osi_core, value, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - } - return ret; -} -#endif - -/** - * @brief mgbe_configure_mac - Configure MAC - * - * Algorithm: This takes care of configuring the below - * parameters for the MAC - * 1) Programming the MAC address - * 2) Enable required MAC control fields in MCR - * 3) Enable Multicast and Broadcast Queue - * 4) Disable MMC nve32_terrupts and Configure the MMC counters - * 5) Enable required MAC nve32_terrupts - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC has to be out of reset. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_configure_mac(struct osi_core_priv_data *osi_core) -{ - unsigned int value = 0U, max_queue = 0U, i = 0U; - - /* TODO: Need to check if we need to enable anything in Tx configuration - * value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MAC_TMCR); - */ - /* Read MAC Rx Configuration Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_RMCR); - /* Enable Automatic Pad or CRC Stripping */ - /* Enable CRC stripping for Type packets */ - /* Enable Rx checksum offload engine by default */ - value |= MGBE_MAC_RMCR_ACS | MGBE_MAC_RMCR_CST | MGBE_MAC_RMCR_IPC; - - /* Jumbo Packet Enable */ - if (osi_core->mtu > OSI_DFLT_MTU_SIZE && - osi_core->mtu <= OSI_MTU_SIZE_9000) { - value |= MGBE_MAC_RMCR_JE; - } else if (osi_core->mtu > OSI_MTU_SIZE_9000){ - /* if MTU greater 9K use GPSLCE */ - value |= MGBE_MAC_RMCR_GPSLCE | MGBE_MAC_RMCR_WD; - value &= ~MGBE_MAC_RMCR_GPSL_MSK; - value |= ((OSI_MAX_MTU_SIZE << 16) & MGBE_MAC_RMCR_GPSL_MSK); - } else { - value &= ~MGBE_MAC_RMCR_JE; - value &= ~MGBE_MAC_RMCR_GPSLCE; - value &= ~MGBE_MAC_RMCR_WD; - } - - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_RMCR); - - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_TMCR); - /* DDIC bit set is needed to improve MACSEC Tput */ - value |= MGBE_MAC_TMCR_DDIC; - /* Jabber Disable */ - if (osi_core->mtu > OSI_DFLT_MTU_SIZE) { - value |= MGBE_MAC_TMCR_JD; - } - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_TMCR); - - /* Enable Multicast and Broadcast Queue */ - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); - value |= MGBE_MAC_RQC1R_MCBCQEN; - /* Set MCBCQ to highest enabled RX queue index */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - if ((max_queue < osi_core->mtl_queues[i]) && - (osi_core->mtl_queues[i] < OSI_MGBE_MAX_NUM_QUEUES)) { - /* Update max queue number */ - max_queue = osi_core->mtl_queues[i]; - } - } - value &= ~(MGBE_MAC_RQC1R_MCBCQ); - value |= (max_queue << MGBE_MAC_RQC1R_MCBCQ_SHIFT); - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_RQC1R); - - /* Disable all MMC nve32_terrupts */ - /* Disable all MMC Tx nve32_terrupts */ - osi_writela(osi_core, OSI_NONE, (nveu8_t *)osi_core->base + - MGBE_MMC_TX_INTR_EN); - /* Disable all MMC RX nve32_terrupts */ - osi_writela(osi_core, OSI_NONE, (nveu8_t *)osi_core->base + - MGBE_MMC_RX_INTR_EN); - - /* Configure MMC counters */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); - value |= MGBE_MMC_CNTRL_CNTRST | MGBE_MMC_CNTRL_RSTONRD | - MGBE_MMC_CNTRL_CNTMCT | MGBE_MMC_CNTRL_CNTPRST; - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_MMC_CNTRL); - - /* Enable MAC nve32_terrupts */ - /* Read MAC IMR Register */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_IER); - /* RGSMIIIM - RGMII/SMII interrupt and TSIE Enable */ - /* TXESIE - Transmit Error Status Interrupt Enable */ - /* TODO: LPI need to be enabled during EEE implementation */ - value |= (MGBE_IMR_RGSMIIIE | MGBE_IMR_TSIE | MGBE_IMR_TXESIE); - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + MGBE_MAC_IER); - - /* Enable common interrupt at wrapper level */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - value |= MGBE_MAC_SBD_INTR; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - - /* Enable VLAN configuration */ - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); - /* Enable VLAN Tag in RX Status - * Disable double VLAN Tag processing on TX and RX - */ - if (osi_core->strip_vlan_tag == OSI_ENABLE) { - /* Enable VLAN Tag stripping always */ - value |= MGBE_MAC_VLANTR_EVLS_ALWAYS_STRIP; - } - value |= MGBE_MAC_VLANTR_EVLRXS | MGBE_MAC_VLANTR_DOVLTC; - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_VLAN_TR); - - value = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); - /* Enable VLAN tagging through context descriptor */ - value |= MGBE_MAC_VLANTIR_VLTI; - /* insert/replace C_VLAN in 13th & 14th bytes of transmitted frames */ - value &= ~MGBE_MAC_VLANTIRR_CSVL; - osi_writela(osi_core, value, - (unsigned char *)osi_core->base + MGBE_MAC_VLANTIR); - - /* Configure default flow control settings */ - if (osi_core->pause_frames == OSI_PAUSE_FRAMES_ENABLE) { - osi_core->flow_ctrl = (OSI_FLOW_CTRL_TX | OSI_FLOW_CTRL_RX); - if (mgbe_config_flow_control(osi_core, - osi_core->flow_ctrl) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Failed to set flow control configuration\n", - 0ULL); - } - } - /* TODO: USP (user Priority) to RxQ Mapping */ - - /* RSS cofiguration */ - return mgbe_config_rss(osi_core); -} - -/** - * @brief mgbe_configure_dma - Configure DMA - * - * Algorithm: This takes care of configuring the below - * parameters for the DMA - * 1) Programming different burst length for the DMA - * 2) Enable enhanced Address mode - * 3) Programming max read outstanding request limit - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC has to be out of reset. - */ -static void mgbe_configure_dma(struct osi_core_priv_data *osi_core, - nveu32_t pre_si) -{ - nveu32_t value = 0; - - /* Set AXI Undefined Burst Length */ - value |= MGBE_DMA_SBUS_UNDEF; - /* AXI Burst Length 256*/ - value |= MGBE_DMA_SBUS_BLEN256; - /* Enhanced Address Mode Enable */ - value |= MGBE_DMA_SBUS_EAME; - /* AXI Maximum Read Outstanding Request Limit = 63 */ - value |= MGBE_DMA_SBUS_RD_OSR_LMT; - /* AXI Maximum Write Outstanding Request Limit = 63 */ - value |= MGBE_DMA_SBUS_WR_OSR_LMT; - - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_DMA_SBUS); - - /* Configure TDPS to 5 */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_DMA_TX_EDMA_CTRL); - if (pre_si == OSI_ENABLE) { - /* For Pre silicon TDPS Value is 3 */ - value |= MGBE_DMA_TX_EDMA_CTRL_TDPS_PRESI; - } else { - value |= MGBE_DMA_TX_EDMA_CTRL_TDPS; - } - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_DMA_TX_EDMA_CTRL); - - /* Configure RDPS to 5 */ - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_DMA_RX_EDMA_CTRL); - if (pre_si == OSI_ENABLE) { - /* For Pre silicon RDPS Value is 3 */ - value |= MGBE_DMA_RX_EDMA_CTRL_RDPS_PRESI; - } else { - value |= MGBE_DMA_RX_EDMA_CTRL_RDPS; - } - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + MGBE_DMA_RX_EDMA_CTRL); -} - -/** - * @brief Initialize the osi_core->backup_config. - * - * Algorithm: Populate the list of core registers to be saved during suspend. - * Fill the address of each register in structure. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval none - */ -static void mgbe_core_backup_init(struct osi_core_priv_data *const osi_core) -{ - struct core_backup *config = &osi_core->backup_config; - unsigned char *base = (unsigned char *)osi_core->base; - unsigned int i; - - /* MAC registers backup */ - config->reg_addr[MGBE_MAC_TMCR_BAK_IDX] = base + MGBE_MAC_TMCR; - config->reg_addr[MGBE_MAC_RMCR_BAK_IDX] = base + MGBE_MAC_RMCR; - config->reg_addr[MGBE_MAC_PFR_BAK_IDX] = base + MGBE_MAC_PFR; - config->reg_addr[MGBE_MAC_VLAN_TAG_BAK_IDX] = base + - MGBE_MAC_VLAN_TR; - config->reg_addr[MGBE_MAC_VLANTIR_BAK_IDX] = base + MGBE_MAC_VLANTIR; - config->reg_addr[MGBE_MAC_RX_FLW_CTRL_BAK_IDX] = base + - MGBE_MAC_RX_FLW_CTRL; - config->reg_addr[MGBE_MAC_RQC0R_BAK_IDX] = base + MGBE_MAC_RQC0R; - config->reg_addr[MGBE_MAC_RQC1R_BAK_IDX] = base + MGBE_MAC_RQC1R; - config->reg_addr[MGBE_MAC_RQC2R_BAK_IDX] = base + MGBE_MAC_RQC2R; - config->reg_addr[MGBE_MAC_ISR_BAK_IDX] = base + MGBE_MAC_ISR; - config->reg_addr[MGBE_MAC_IER_BAK_IDX] = base + MGBE_MAC_IER; - config->reg_addr[MGBE_MAC_PMTCSR_BAK_IDX] = base + MGBE_MAC_PMTCSR; - config->reg_addr[MGBE_MAC_LPI_CSR_BAK_IDX] = base + MGBE_MAC_LPI_CSR; - config->reg_addr[MGBE_MAC_LPI_TIMER_CTRL_BAK_IDX] = base + - MGBE_MAC_LPI_TIMER_CTRL; - config->reg_addr[MGBE_MAC_LPI_EN_TIMER_BAK_IDX] = base + - MGBE_MAC_LPI_EN_TIMER; - config->reg_addr[MGBE_MAC_TCR_BAK_IDX] = base + MGBE_MAC_TCR; - config->reg_addr[MGBE_MAC_SSIR_BAK_IDX] = base + MGBE_MAC_SSIR; - config->reg_addr[MGBE_MAC_STSR_BAK_IDX] = base + MGBE_MAC_STSR; - config->reg_addr[MGBE_MAC_STNSR_BAK_IDX] = base + MGBE_MAC_STNSR; - config->reg_addr[MGBE_MAC_STSUR_BAK_IDX] = base + MGBE_MAC_STSUR; - config->reg_addr[MGBE_MAC_STNSUR_BAK_IDX] = base + MGBE_MAC_STNSUR; - config->reg_addr[MGBE_MAC_TAR_BAK_IDX] = base + MGBE_MAC_TAR; - config->reg_addr[MGBE_DMA_BMR_BAK_IDX] = base + MGBE_DMA_MODE; - config->reg_addr[MGBE_DMA_SBUS_BAK_IDX] = base + MGBE_DMA_SBUS; - config->reg_addr[MGBE_DMA_ISR_BAK_IDX] = base + MGBE_DMA_ISR; - config->reg_addr[MGBE_MTL_OP_MODE_BAK_IDX] = base + MGBE_MTL_OP_MODE; - config->reg_addr[MGBE_MTL_RXQ_DMA_MAP0_BAK_IDX] = base + - MGBE_MTL_RXQ_DMA_MAP0; - - for (i = 0; i < MGBE_MAX_HTR_REGS; i++) { - config->reg_addr[MGBE_MAC_HTR_REG_BAK_IDX(i)] = base + - MGBE_MAC_HTR_REG(i); - } - for (i = 0; i < OSI_MGBE_MAX_NUM_QUEUES; i++) { - config->reg_addr[MGBE_MAC_QX_TX_FLW_CTRL_BAK_IDX(i)] = base + - MGBE_MAC_QX_TX_FLW_CTRL(i); - } - for (i = 0; i < OSI_MGBE_MAX_MAC_ADDRESS_FILTER; i++) { - config->reg_addr[MGBE_MAC_ADDRH_BAK_IDX(i)] = base + - MGBE_MAC_ADDRH(i); - config->reg_addr[MGBE_MAC_ADDRL_BAK_IDX(i)] = base + - MGBE_MAC_ADDRL(i); - } - for (i = 0; i < OSI_MGBE_MAX_NUM_QUEUES; i++) { - config->reg_addr[MGBE_MTL_CHX_TX_OP_MODE_BAK_IDX(i)] = base + - MGBE_MTL_CHX_TX_OP_MODE(i); - config->reg_addr[MGBE_MTL_CHX_RX_OP_MODE_BAK_IDX(i)] = base + - MGBE_MTL_CHX_RX_OP_MODE(i); - } - for (i = 0; i < OSI_MAX_TC_NUM; i++) { - config->reg_addr[MGBE_MTL_TXQ_ETS_CR_BAK_IDX(i)] = base + - MGBE_MTL_TCQ_ETS_CR(i); - config->reg_addr[MGBE_MTL_TXQ_QW_BAK_IDX(i)] = base + - MGBE_MTL_TCQ_QW(i); - config->reg_addr[MGBE_MTL_TXQ_ETS_SSCR_BAK_IDX(i)] = base + - MGBE_MTL_TCQ_ETS_SSCR(i); - config->reg_addr[MGBE_MTL_TXQ_ETS_HCR_BAK_IDX(i)] = base + - MGBE_MTL_TCQ_ETS_HCR(i); - config->reg_addr[MGBE_MTL_TXQ_ETS_LCR_BAK_IDX(i)] = base + - MGBE_MTL_TCQ_ETS_LCR(i); - } - - /* TODO: Add wrapper register backup */ -} - -/** - * @brief mgbe_enable_mtl_interrupts - Enable MTL interrupts - * - * Algorithm: enable MTL interrupts for EST - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void mgbe_enable_mtl_interrupts( - struct osi_core_priv_data *osi_core) -{ - unsigned int mtl_est_ir = OSI_DISABLE; - - mtl_est_ir = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MTL_EST_ITRE); - /* enable only MTL interrupt realted to - * Constant Gate Control Error - * Head-Of-Line Blocking due to Scheduling - * Head-Of-Line Blocking due to Frame Size - * BTR Error - * Switch to S/W owned list Complete - */ - mtl_est_ir |= (MGBE_MTL_EST_ITRE_CGCE | MGBE_MTL_EST_ITRE_IEHS | - MGBE_MTL_EST_ITRE_IEHF | MGBE_MTL_EST_ITRE_IEBE | - MGBE_MTL_EST_ITRE_IECC); - osi_writela(osi_core, mtl_est_ir, - (unsigned char *)osi_core->base + MGBE_MTL_EST_ITRE); -} - -/** - * @brief mgbe_enable_fpe_interrupts - Enable MTL interrupts - * - * Algorithm: enable FPE interrupts - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void mgbe_enable_fpe_interrupts( - struct osi_core_priv_data *osi_core) -{ - unsigned int value = OSI_DISABLE; - - /* Read MAC IER Register and enable Frame Preemption Interrupt - * Enable */ - value = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_IER); - value |= MGBE_IMR_FPEIE; - osi_writela(osi_core, value, (unsigned char *) - osi_core->base + MGBE_MAC_IER); -} - -/** - * @brief mgbe_save_gcl_params - save GCL configs in local core structure - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static inline void mgbe_save_gcl_params(struct osi_core_priv_data *osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int gcl_widhth[4] = {0, OSI_MAX_24BITS, OSI_MAX_28BITS, - OSI_MAX_32BITS}; - nveu32_t gcl_ti_mask[4] = {0, OSI_MASK_16BITS, OSI_MASK_20BITS, - OSI_MASK_24BITS}; - unsigned int gcl_depthth[6] = {0, OSI_GCL_SIZE_64, OSI_GCL_SIZE_128, - OSI_GCL_SIZE_256, OSI_GCL_SIZE_512, - OSI_GCL_SIZE_1024}; - - if (osi_core->hw_feature->gcl_width == 0 || - osi_core->hw_feature->gcl_width > 3) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL width\n", - (unsigned long long)osi_core->hw_feature->gcl_width); - } else { - l_core->gcl_width_val = - gcl_widhth[osi_core->hw_feature->gcl_width]; - l_core->ti_mask = gcl_ti_mask[osi_core->hw_feature->gcl_width]; - } - - if (osi_core->hw_feature->gcl_depth == 0 || - osi_core->hw_feature->gcl_depth > 5) { - /* Do Nothing */ - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Wrong HW feature GCL depth\n", - (unsigned long long)osi_core->hw_feature->gcl_depth); - } else { - l_core->gcl_dep = gcl_depthth[osi_core->hw_feature->gcl_depth]; - } -} - -/** - * @brief mgbe_tsn_init - initialize TSN feature - * - * Algorithm: - * 1) If hardware support EST, - * a) Set default EST configuration - * b) Set enable interrupts - * 2) If hardware supports FPE - * a) Set default FPE configuration - * b) enable interrupts - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est_sel: EST HW support present or not - * @param[in] fpe_sel: FPE HW support present or not - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_tsn_init(struct osi_core_priv_data *osi_core, - unsigned int est_sel, unsigned int fpe_sel) -{ - unsigned int val = 0x0; - unsigned int temp = 0U; - - if (est_sel == OSI_ENABLE) { - mgbe_save_gcl_params(osi_core); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_EST_CONTROL); - - /* - * PTOV PTP clock period * 6 - * dual-port RAM based asynchronous FIFO controllers or - * Single-port RAM based synchronous FIFO controllers - * CTOV 96 x Tx clock period - * : - * : - * set other default value - */ - val &= ~MGBE_MTL_EST_CONTROL_PTOV; - if (osi_core->pre_si == OSI_ENABLE) { - /* 6*1/(78.6 MHz) in ns*/ - temp = (6U * 13U); - } else { - temp = MGBE_MTL_EST_PTOV_RECOMMEND; - } - temp = temp << MGBE_MTL_EST_CONTROL_PTOV_SHIFT; - val |= temp; - - val &= ~MGBE_MTL_EST_CONTROL_CTOV; - temp = MGBE_MTL_EST_CTOV_RECOMMEND; - temp = temp << MGBE_MTL_EST_CONTROL_CTOV_SHIFT; - val |= temp; - - /*Loop Count to report Scheduling Error*/ - val &= ~MGBE_MTL_EST_CONTROL_LCSE; - val |= MGBE_MTL_EST_CONTROL_LCSE_VAL; - - val &= ~MGBE_MTL_EST_CONTROL_DDBF; - val |= MGBE_MTL_EST_CONTROL_DDBF; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_MTL_EST_CONTROL); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_OVERHEAD); - val &= ~MGBE_MTL_EST_OVERHEAD_OVHD; - /* As per hardware programming info */ - val |= MGBE_MTL_EST_OVERHEAD_RECOMMEND; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_OVERHEAD); - - mgbe_enable_mtl_interrupts(osi_core); - } - - if (fpe_sel == OSI_ENABLE) { - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MAC_RQC1R); - val &= ~MGBE_MAC_RQC1R_RQ; - temp = osi_core->residual_queue; - temp = temp << MGBE_MAC_RQC1R_RQ_SHIFT; - temp = (temp & MGBE_MAC_RQC1R_RQ); - val |= temp; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_MAC_RQC1R); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_RQC4R); - val &= ~MGBE_MAC_RQC4R_PMCBCQ; - temp = osi_core->residual_queue; - temp = temp << MGBE_MAC_RQC4R_PMCBCQ_SHIFT; - temp = (temp & MGBE_MAC_RQC4R_PMCBCQ); - val |= temp; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MAC_RQC4R); - - mgbe_enable_fpe_interrupts(osi_core); - } - - /* CBS setting for TC or TXQ for default configuration - user application should use IOCTL to set CBS as per requirement - */ -} - -/** - * @brief Map DMA channels to a specific VM IRQ. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note OSD layer needs to update number of VM channels and - * DMA channel list in osi_vm_irq_data. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_dma_chan_to_vmirq_map(struct osi_core_priv_data *osi_core) -{ - nveu32_t sid[4] = { MGBE0_SID, MGBE1_SID, MGBE2_SID, MGBE3_SID }; - struct osi_vm_irq_data *irq_data; - nveu32_t i, j; - nveu32_t chan; - - for (i = 0; i < osi_core->num_vm_irqs; i++) { - irq_data = &osi_core->irq_data[i]; - - for (j = 0; j < irq_data->num_vm_chans; j++) { - chan = irq_data->vm_chans[j]; - - if (chan >= OSI_MGBE_MAX_NUM_CHANS) { - continue; - } - - osi_writel(OSI_BIT(irq_data->vm_num), - (nveu8_t *)osi_core->base + - MGBE_VIRT_INTR_APB_CHX_CNTRL(chan)); - } - osi_writel(OSI_BIT(irq_data->vm_num), - (nveu8_t *)osi_core->base + MGBE_VIRTUAL_APB_ERR_CTRL); - } - - if ((osi_core->use_virtualization == OSI_DISABLE) && - (osi_core->hv_base != OSI_NULL)) { - if (osi_core->instance_id > 3U) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "Wrong MAC instance-ID\n", - osi_core->instance_id); - return -1; - } - - osi_writela(osi_core, MGBE_SID_VAL1(sid[osi_core->instance_id]), - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID0_CTRL); - - osi_writela(osi_core, MGBE_SID_VAL1(sid[osi_core->instance_id]), - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID1_CTRL); - - osi_writela(osi_core, MGBE_SID_VAL2(sid[osi_core->instance_id]), - (nveu8_t *)osi_core->hv_base + - MGBE_WRAP_AXI_ASID2_CTRL); - } - - return 0; -} - - -/** - * @brief mgbe_core_init - MGBE MAC, MTL and common DMA Initialization - * - * Algorithm: This function will take care of initializing MAC, MTL and - * common DMA registers. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_fifo_size: MTL TX FIFO size - * @param[in] rx_fifo_size: MTL RX FIFO size - * - * @note 1) MAC should be out of reset. See osi_poll_for_swr() for details. - * 2) osi_core->base needs to be filled based on ioremap. - * 3) osi_core->num_mtl_queues needs to be filled. - * 4) osi_core->mtl_queues[qinx] need to be filled. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_core_init(struct osi_core_priv_data *osi_core, - nveu32_t tx_fifo_size, - nveu32_t rx_fifo_size) -{ - nve32_t ret = 0; - nveu32_t qinx = 0; - nveu32_t value = 0; - nveu32_t tx_fifo = 0; - nveu32_t rx_fifo = 0; - - mgbe_core_backup_init(osi_core); - - /* reset mmc counters */ - osi_writela(osi_core, MGBE_MMC_CNTRL_CNTRST, (nveu8_t *)osi_core->base + - MGBE_MMC_CNTRL); - - /* Mapping MTL Rx queue and DMA Rx channel */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP0); - value |= MGBE_RXQ_TO_DMA_CHAN_MAP0; - value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP0); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP1); - value |= MGBE_RXQ_TO_DMA_CHAN_MAP1; - value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP1); - - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP2); - value |= MGBE_RXQ_TO_DMA_CHAN_MAP2; - value |= MGBE_RXQ_TO_DMA_MAP_DDMACH; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_RXQ_DMA_MAP2); - - /* Enable XDCS in MAC_Extended_Configuration */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - value |= MGBE_MAC_EXT_CNF_DDS; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - - if (osi_core->pre_si == OSI_ENABLE) { - /* For pre silicon Tx and Rx Queue sizes are 64KB */ - tx_fifo_size = MGBE_TX_FIFO_SIZE_64KB; - rx_fifo_size = MGBE_RX_FIFO_SIZE_64KB; - } else { - /* Actual HW RAM size for Tx is 128KB and Rx is 192KB */ - tx_fifo_size = MGBE_TX_FIFO_SIZE_128KB; - rx_fifo_size = MGBE_RX_FIFO_SIZE_192KB; - } - - /* Calculate value of Transmit queue fifo size to be programmed */ - tx_fifo = mgbe_calculate_per_queue_fifo(tx_fifo_size, - osi_core->num_mtl_queues); - - /* Calculate value of Receive queue fifo size to be programmed */ - rx_fifo = mgbe_calculate_per_queue_fifo(rx_fifo_size, - osi_core->num_mtl_queues); - - /* Configure MTL Queues */ - /* TODO: Iterate over Number MTL queues need to be removed */ - for (qinx = 0; qinx < osi_core->num_mtl_queues; qinx++) { - ret = mgbe_configure_mtl_queue(osi_core->mtl_queues[qinx], - osi_core, tx_fifo, rx_fifo); - if (ret < 0) { - return ret; - } - } - - /* configure MGBE MAC HW */ - ret = mgbe_configure_mac(osi_core); - if (ret < 0) { - return ret; - } - - /* configure MGBE DMA */ - mgbe_configure_dma(osi_core, osi_core->pre_si); - - /* tsn initialization */ - if (osi_core->hw_feature != OSI_NULL) { - mgbe_tsn_init(osi_core, osi_core->hw_feature->est_sel, - osi_core->hw_feature->fpe_sel); - } - - return mgbe_dma_chan_to_vmirq_map(osi_core); -} - -/** - * @brief mgbe_handle_mac_fpe_intrs - * - * Algorithm: This function takes care of handling the - * MAC FPE interrupts. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC interrupts need to be enabled - * - */ -static void mgbe_handle_mac_fpe_intrs(struct osi_core_priv_data *osi_core) -{ - unsigned int val = 0; - - /* interrupt bit clear on read as CSR_SW is reset */ - val = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_FPE_CTS); - - if ((val & MGBE_MAC_FPE_CTS_RVER) == MGBE_MAC_FPE_CTS_RVER) { - val &= ~MGBE_MAC_FPE_CTS_RVER; - val |= MGBE_MAC_FPE_CTS_SRSP; - } - - if ((val & MGBE_MAC_FPE_CTS_RRSP) == MGBE_MAC_FPE_CTS_RRSP) { - /* received respose packet Nothing to be done, it means other - * IP also support FPE - */ - val &= ~MGBE_MAC_FPE_CTS_RRSP; - val &= ~MGBE_MAC_FPE_CTS_TVER; - osi_core->fpe_ready = OSI_ENABLE; - val |= MGBE_MAC_FPE_CTS_EFPE; - } - - if ((val & MGBE_MAC_FPE_CTS_TRSP) == MGBE_MAC_FPE_CTS_TRSP) { - /* TX response packet sucessful */ - osi_core->fpe_ready = OSI_ENABLE; - /* Enable frame preemption */ - val &= ~MGBE_MAC_FPE_CTS_TRSP; - val &= ~MGBE_MAC_FPE_CTS_TVER; - val |= MGBE_MAC_FPE_CTS_EFPE; - } - - if ((val & MGBE_MAC_FPE_CTS_TVER) == MGBE_MAC_FPE_CTS_TVER) { - /*Transmit verif packet sucessful*/ - osi_core->fpe_ready = OSI_DISABLE; - val &= ~MGBE_MAC_FPE_CTS_TVER; - val &= ~MGBE_MAC_FPE_CTS_EFPE; - } - - osi_writela(osi_core, val, (unsigned char *) - osi_core->base + MGBE_MAC_FPE_CTS); -} - -/** - * @brief Get free timestamp index from TS array by validating in_use param - * - * @param[in] l_core: Core local private data structure. - * - * @retval Free timestamp index. - * - * @post If timestamp index is MAX_TX_TS_CNT, then its no free count index - * is available. - */ -static inline nveu32_t get_free_ts_idx(struct core_local *l_core) -{ - nveu32_t i; - - for (i = 0; i < MAX_TX_TS_CNT; i++) { - if (l_core->ts[i].in_use == OSI_NONE) { - break; - } - } - return i; -} - -/** - * @brief mgbe_handle_mac_intrs - Handle MAC interrupts - * - * Algorithm: This function takes care of handling the - * MAC nve32_terrupts which includes speed, mode detection. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dma_isr: DMA ISR register read value. - * - * @note MAC nve32_terrupts need to be enabled - */ -static void mgbe_handle_mac_intrs(struct osi_core_priv_data *osi_core, - nveu32_t dma_isr) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nveu32_t mac_isr = 0; - nveu32_t mac_ier = 0; - nveu32_t tx_errors = 0; - - mac_isr = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_ISR); - /* Handle MAC interrupts */ - if ((dma_isr & MGBE_DMA_ISR_MACIS) != MGBE_DMA_ISR_MACIS) { - return; - } - - mac_ier = osi_readla(osi_core, - (unsigned char *)osi_core->base + MGBE_MAC_IER); - if (((mac_isr & MGBE_MAC_IMR_FPEIS) == MGBE_MAC_IMR_FPEIS) && - ((mac_ier & MGBE_IMR_FPEIE) == MGBE_IMR_FPEIE)) { - mgbe_handle_mac_fpe_intrs(osi_core); - mac_isr &= ~MGBE_MAC_IMR_FPEIS; - } - /* Check for any MAC Transmit Error Status Interrupt */ - if ((mac_isr & MGBE_IMR_TXESIE) == MGBE_IMR_TXESIE) { - /* Check for the type of Tx error by reading MAC_Rx_Tx_Status - * register - */ - tx_errors = osi_readl((unsigned char *)osi_core->base + - MGBE_MAC_RX_TX_STS); - if ((tx_errors & MGBE_MAC_TX_TJT) == MGBE_MAC_TX_TJT) { - /* increment Tx Jabber timeout stats */ - osi_core->pkt_err_stats.mgbe_jabber_timeout_err = - osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_jabber_timeout_err, - 1UL); - } - if ((tx_errors & MGBE_MAC_TX_IHE) == MGBE_MAC_TX_IHE) { - /* IP Header Error */ - osi_core->pkt_err_stats.mgbe_ip_header_err = - osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_ip_header_err, - 1UL); - } - if ((tx_errors & MGBE_MAC_TX_PCE) == MGBE_MAC_TX_PCE) { - /* Payload Checksum error */ - osi_core->pkt_err_stats.mgbe_payload_cs_err = - osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_payload_cs_err, - 1UL); - } - } - - osi_writela(osi_core, mac_isr, - (unsigned char *)osi_core->base + MGBE_MAC_ISR); - if ((mac_isr & MGBE_ISR_TSIS) == MGBE_ISR_TSIS) { - struct osi_core_tx_ts *head = &l_core->tx_ts_head; - - if (__sync_fetch_and_add(&l_core->ts_lock, 1) == 1U) { - /* mask return as initial value is returned always */ - (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); - osi_core->xstats.ts_lock_add_fail = - osi_update_stats_counter( - osi_core->xstats.ts_lock_add_fail, 1U); - goto done; - } - - /* TXTSC bit should get reset when all timestamp read */ - while (((osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_TSS) & - MGBE_MAC_TSS_TXTSC) == MGBE_MAC_TSS_TXTSC)) { - nveu32_t i = get_free_ts_idx(l_core); - - if (i == MAX_TX_TS_CNT) { - struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; - /* Remove oldest stale TS from list to make space for new TS */ - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "Removing TS from queue pkt_id\n", temp->pkt_id); - - temp->in_use = OSI_DISABLE; - /* remove temp node from the link */ - temp->next->prev = temp->prev; - temp->prev->next = temp->next; - i = get_free_ts_idx(l_core); - if (i == MAX_TX_TS_CNT) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "TS queue is full\n", i); - break; - } - } - - l_core->ts[i].nsec = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_TSNSSEC); - - l_core->ts[i].in_use = OSI_ENABLE; - l_core->ts[i].pkt_id = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_TSPKID); - l_core->ts[i].sec = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MAC_TSSEC); - /* Add time stamp to end of list */ - l_core->ts[i].next = head->prev->next; - head->prev->next = &l_core->ts[i]; - l_core->ts[i].prev = head->prev; - head->prev = &l_core->ts[i]; - } - - /* mask return as initial value is returned always */ - (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); - } -done: - mac_isr &= ~MGBE_ISR_TSIS; - - osi_writela(osi_core, mac_isr, - (unsigned char *)osi_core->base + MGBE_MAC_ISR); - /* TODO: Duplex/speed settigs - Its not same as EQOS for MGBE */ -} - -/** - * @brief mgbe_update_dma_sr_stats - stats for dma_status error - * - * Algorithm: increament error stats based on corresponding bit filed. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] dma_sr: Dma status register read value - * @param[in] qinx: Queue index - */ -static inline void mgbe_update_dma_sr_stats(struct osi_core_priv_data *osi_core, - nveu32_t dma_sr, nveu32_t qinx) -{ - nveu64_t val; - - if ((dma_sr & MGBE_DMA_CHX_STATUS_RBU) == MGBE_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 & MGBE_DMA_CHX_STATUS_TPS) == MGBE_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 & MGBE_DMA_CHX_STATUS_TBU) == MGBE_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 & MGBE_DMA_CHX_STATUS_RPS) == MGBE_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 & MGBE_DMA_CHX_STATUS_FBE) == MGBE_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); - } -} - -/** - * @brief mgbe_set_avb_algorithm - Set TxQ/TC avb config - * - * Algorithm: - * 1) Check if queue index is valid - * 2) Update operation mode of TxQ/TC - * 2a) Set TxQ operation mode - * 2b) Set Algo and Credit contro - * 2c) Set Send slope credit - * 2d) Set Idle slope credit - * 2e) Set Hi credit - * 2f) Set low credit - * 3) Update register values - * - * @param[in] osi_core: osi core priv data structure - * @param[in] avb: structure having configuration for avb algorithm - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_set_avb_algorithm( - struct osi_core_priv_data *const osi_core, - const struct osi_core_avb_algorithm *const avb) -{ - unsigned int value; - int ret = -1; - unsigned int qinx = 0U; - unsigned int tcinx = 0U; - - if (avb == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", - 0ULL); - return ret; - } - - /* queue index in range */ - if (avb->qindex >= OSI_MGBE_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", - (unsigned long long)avb->qindex); - return ret; - } - - /* queue oper_mode in range check*/ - if (avb->oper_mode >= OSI_MTL_QUEUE_MODEMAX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue mode\n", - (unsigned long long)avb->qindex); - return ret; - } - - /* Validate algo is valid */ - if (avb->algo > OSI_MTL_TXQ_AVALG_CBS) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Algo input\n", - (unsigned long long)avb->tcindex); - return ret; - } - - /* can't set AVB mode for queue 0 */ - if ((avb->qindex == 0U) && (avb->oper_mode == OSI_MTL_QUEUE_AVB)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_OPNOTSUPP, - "Not allowed to set AVB for Q0\n", - (unsigned long long)avb->qindex); - return ret; - } - - /* TC index range check */ - if ((avb->tcindex == 0U) || (avb->tcindex >= OSI_MAX_TC_NUM)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue TC mapping\n", - (unsigned long long)avb->tcindex); - return ret; - } - - qinx = avb->qindex; - tcinx = avb->tcindex; - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - value &= ~MGBE_MTL_TX_OP_MODE_TXQEN; - /* Set TXQEN mode as per input struct after masking 3 bit */ - value |= ((avb->oper_mode << MGBE_MTL_TX_OP_MODE_TXQEN_SHIFT) & - MGBE_MTL_TX_OP_MODE_TXQEN); - /* Set TC mapping */ - value &= ~MGBE_MTL_TX_OP_MODE_Q2TCMAP; - value |= ((tcinx << MGBE_MTL_TX_OP_MODE_Q2TCMAP_SHIFT) & - MGBE_MTL_TX_OP_MODE_Q2TCMAP); - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - - /* Set Algo and Credit control */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_CR(tcinx)); - if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { - value &= ~MGBE_MTL_TCQ_ETS_CR_CC; - value |= (avb->credit_control << MGBE_MTL_TCQ_ETS_CR_CC_SHIFT) & - MGBE_MTL_TCQ_ETS_CR_CC; - } - value &= ~MGBE_MTL_TCQ_ETS_CR_AVALG; - value |= (avb->algo << MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT) & - MGBE_MTL_TCQ_ETS_CR_AVALG; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_CR(tcinx)); - - if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { - /* Set Idle slope credit*/ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_QW(tcinx)); - value &= ~MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK; - value |= avb->idle_slope & MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_QW(tcinx)); - - /* Set Send slope credit */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_SSCR(tcinx)); - value &= ~MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK; - value |= avb->send_slope & MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_SSCR(tcinx)); - - /* Set Hi credit */ - value = avb->hi_credit & MGBE_MTL_TCQ_ETS_HCR_HC_MASK; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_HCR(tcinx)); - - /* low credit is -ve number, osi_write need a unsigned int - * take only 28:0 bits from avb->low_credit - */ - value = avb->low_credit & MGBE_MTL_TCQ_ETS_LCR_LC_MASK; - osi_writela(osi_core, value, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_LCR(tcinx)); - } - - return 0; -} - -/** - * @brief mgbe_get_avb_algorithm - Get TxQ/TC avb config - * - * Algorithm: - * 1) Check if queue index is valid - * 2) read operation mode of TxQ/TC - * 2a) read TxQ operation mode - * 2b) read Algo and Credit contro - * 2c) read Send slope credit - * 2d) read Idle slope credit - * 2e) read Hi credit - * 2f) read low credit - * 3) updated pointer - * - * @param[in] osi_core: osi core priv data structure - * @param[out] avb: structure pointer having configuration for avb algorithm - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_get_avb_algorithm(struct osi_core_priv_data *const osi_core, - struct osi_core_avb_algorithm *const avb) -{ - unsigned int value; - int ret = -1; - unsigned int qinx = 0U; - unsigned int tcinx = 0U; - - if (avb == OSI_NULL) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "avb structure is NULL\n", - 0ULL); - return ret; - } - - if (avb->qindex >= OSI_MGBE_MAX_NUM_QUEUES) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid Queue index\n", - (unsigned long long)avb->qindex); - return ret; - } - - qinx = avb->qindex; - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_CHX_TX_OP_MODE(qinx)); - - /* Get TxQ/TC mode as per input struct after masking 3:2 bit */ - avb->oper_mode = (value & MGBE_MTL_TX_OP_MODE_TXQEN) >> - MGBE_MTL_TX_OP_MODE_TXQEN_SHIFT; - - /* Get Queue Traffic Class Mapping */ - avb->tcindex = ((value & MGBE_MTL_TX_OP_MODE_Q2TCMAP) >> - MGBE_MTL_TX_OP_MODE_Q2TCMAP_SHIFT); - tcinx = avb->tcindex; - - /* Get Algo and Credit control */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_CR(tcinx)); - avb->credit_control = (value & MGBE_MTL_TCQ_ETS_CR_CC) >> - MGBE_MTL_TCQ_ETS_CR_CC_SHIFT; - avb->algo = (value & MGBE_MTL_TCQ_ETS_CR_AVALG) >> - MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT; - - if (avb->algo == OSI_MTL_TXQ_AVALG_CBS) { - /* Get Idle slope credit*/ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_QW(tcinx)); - avb->idle_slope = value & MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK; - - /* Get Send slope credit */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_SSCR(tcinx)); - avb->send_slope = value & MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK; - - /* Get Hi credit */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_HCR(tcinx)); - avb->hi_credit = value & MGBE_MTL_TCQ_ETS_HCR_HC_MASK; - - /* Get Low credit for which bit 31:29 are unknown - * return 28:0 valid bits to application - */ - value = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_TCQ_ETS_LCR(tcinx)); - avb->low_credit = value & MGBE_MTL_TCQ_ETS_LCR_LC_MASK; - } - - return 0; -} - -/** - * @brief mgbe_handle_mtl_intrs - Handle MTL interrupts - * - * Algorithm: Code to handle interrupt for MTL EST error and status. - * There are possible 4 errors which can be part of common interrupt in case of - * MTL_EST_SCH_ERR (sheduling error)- HLBS - * MTL_EST_FRMS_ERR (Frame size error) - HLBF - * MTL_EST_FRMC_ERR (frame check error) - HLBF - * Constant Gate Control Error - when time interval in less - * than or equal to cycle time, llr = 1 - * There is one status interrupt which says swich to SWOL complete. - * - * @param[in] osi_core: osi core priv data structure - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_handle_mtl_intrs(struct osi_core_priv_data *osi_core, - unsigned int mtl_isr) -{ - unsigned int val = 0U; - unsigned int sch_err = 0U; - unsigned int frm_err = 0U; - unsigned int temp = 0U; - unsigned int i = 0; - unsigned long stat_val = 0U; - unsigned int value = 0U; - unsigned int qstatus = 0U; - unsigned int qinx = 0U; - - /* Check for all MTL queues */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - qinx = osi_core->mtl_queues[i]; - if (mtl_isr & OSI_BIT(qinx)) { - /* check if Q has underflow error */ - qstatus = osi_readl((unsigned char *)osi_core->base + - MGBE_MTL_QINT_STATUS(qinx)); - /* Transmit Queue Underflow Interrupt Status */ - if (qstatus & MGBE_MTL_QINT_TXUNIFS) { - osi_core->pkt_err_stats.mgbe_tx_underflow_err = - osi_update_stats_counter( - osi_core->pkt_err_stats.mgbe_tx_underflow_err, - 1UL); - } - /* Clear interrupt status by writing back with 1 */ - osi_writel(1U, (unsigned char *)osi_core->base + - MGBE_MTL_QINT_STATUS(qinx)); - } - } - - if ((mtl_isr & MGBE_MTL_IS_ESTIS) != MGBE_MTL_IS_ESTIS) { - return; - } - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); - val &= (MGBE_MTL_EST_STATUS_CGCE | MGBE_MTL_EST_STATUS_HLBS | - MGBE_MTL_EST_STATUS_HLBF | MGBE_MTL_EST_STATUS_BTRE | - MGBE_MTL_EST_STATUS_SWLC); - - /* return if interrupt is not related to EST */ - if (val == OSI_DISABLE) { - return; - } - - /* increase counter write 1 back will clear */ - if ((val & MGBE_MTL_EST_STATUS_CGCE) == MGBE_MTL_EST_STATUS_CGCE) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.const_gate_ctr_err; - osi_core->tsn_stats.const_gate_ctr_err = - osi_update_stats_counter(stat_val, 1U); - } - - if ((val & MGBE_MTL_EST_STATUS_HLBS) == MGBE_MTL_EST_STATUS_HLBS) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.head_of_line_blk_sch; - osi_core->tsn_stats.head_of_line_blk_sch = - osi_update_stats_counter(stat_val, 1U); - /* Need to read MTL_EST_Sch_Error register and cleared */ - sch_err = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_SCH_ERR); - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - temp = OSI_ENABLE; - temp = temp << i; - if ((sch_err & temp) == temp) { - stat_val = osi_core->tsn_stats.hlbs_q[i]; - osi_core->tsn_stats.hlbs_q[i] = - osi_update_stats_counter(stat_val, 1U); - } - } - sch_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writela(osi_core, sch_err, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_SCH_ERR); - /* Reset EST with print to configure it properly */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - value &= ~MGBE_MTL_EST_EEST; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Disabling EST due to HLBS, correct GCL\n", OSI_NONE); - } - - if ((val & MGBE_MTL_EST_STATUS_HLBF) == MGBE_MTL_EST_STATUS_HLBF) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.head_of_line_blk_frm; - osi_core->tsn_stats.head_of_line_blk_frm = - osi_update_stats_counter(stat_val, 1U); - /* Need to read MTL_EST_Frm_Size_Error register and cleared */ - frm_err = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_FRMS_ERR); - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - temp = OSI_ENABLE; - temp = temp << i; - if ((frm_err & temp) == temp) { - stat_val = osi_core->tsn_stats.hlbf_q[i]; - osi_core->tsn_stats.hlbf_q[i] = - osi_update_stats_counter(stat_val, 1U); - } - } - frm_err &= 0xFFU; //only 8 TC allowed so clearing all - osi_writela(osi_core, frm_err, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_FRMS_ERR); - - /* Reset EST with print to configure it properly */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - /* DDBF 1 means don't drop packets */ - if ((value & MGBE_MTL_EST_CONTROL_DDBF) == - MGBE_MTL_EST_CONTROL_DDBF) { - value &= ~MGBE_MTL_EST_EEST; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Disabling EST due to HLBF, correct GCL\n", - OSI_NONE); - } - } - - if ((val & MGBE_MTL_EST_STATUS_SWLC) == MGBE_MTL_EST_STATUS_SWLC) { - if ((val & MGBE_MTL_EST_STATUS_BTRE) != - MGBE_MTL_EST_STATUS_BTRE) { - osi_core->est_ready = OSI_ENABLE; - } - stat_val = osi_core->tsn_stats.sw_own_list_complete; - osi_core->tsn_stats.sw_own_list_complete = - osi_update_stats_counter(stat_val, 1U); - } - - if ((val & MGBE_MTL_EST_STATUS_BTRE) == MGBE_MTL_EST_STATUS_BTRE) { - osi_core->est_ready = OSI_DISABLE; - stat_val = osi_core->tsn_stats.base_time_reg_err; - osi_core->tsn_stats.base_time_reg_err = - osi_update_stats_counter(stat_val, 1U); - osi_core->est_ready = OSI_DISABLE; - } - /* clear EST status register as interrupt is handled */ - osi_writela(osi_core, val, - (nveu8_t *)osi_core->base + MGBE_MTL_EST_STATUS); - - mtl_isr &= ~MGBE_MTL_IS_ESTIS; - osi_writela(osi_core, mtl_isr, (unsigned char *)osi_core->base + - MGBE_MTL_INTR_STATUS); -} - -/** - * @brief mgbe_config_ptp_offload - Enable/Disable PTP offload - * - * Algorithm: Based on input argument, update PTO and TSCR registers. - * Update ptp_filter for TSCR register. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) configure_ptp() should be called after this API - * - * @retval 0 on success - * @retval -1 on failure. - */ - -static int mgbe_config_ptp_offload(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config) -{ - unsigned char *addr = (unsigned char *)osi_core->base; - int ret = 0; - unsigned int value = 0x0U; - unsigned int ptc_value = 0x0U; - unsigned int port_id = 0x0U; - - /* Read MAC TCR */ - value = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_TCR); - /* clear old configuration */ - - value &= ~(MGBE_MAC_TCR_TSENMACADDR | OSI_MAC_TCR_SNAPTYPSEL_3 | - OSI_MAC_TCR_TSMASTERENA | OSI_MAC_TCR_TSEVENTENA | - OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR | OSI_MAC_TCR_TSVER2ENA | - OSI_MAC_TCR_TSIPENA); - - /** Handle PTO disable */ - if (pto_config->en_dis == OSI_DISABLE) { - /* update global setting in ptp_filter */ - osi_core->ptp_config.ptp_filter = value; - osi_writela(osi_core, ptc_value, addr + MGBE_MAC_PTO_CR); - osi_writela(osi_core, value, addr + MGBE_MAC_TCR); - /* Setting PORT ID as 0 */ - osi_writela(osi_core, OSI_NONE, addr + MGBE_MAC_PIDR0); - osi_writela(osi_core, OSI_NONE, addr + MGBE_MAC_PIDR1); - osi_writela(osi_core, OSI_NONE, addr + MGBE_MAC_PIDR2); - return 0; - } - - /** Handle PTO enable */ - /* Set PTOEN bit */ - ptc_value |= MGBE_MAC_PTO_CR_PTOEN; - ptc_value |= ((pto_config->domain_num << MGBE_MAC_PTO_CR_DN_SHIFT) - & MGBE_MAC_PTO_CR_DN); - - /* Set TSCR register flag */ - value |= (OSI_MAC_TCR_TSENA | OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR | OSI_MAC_TCR_TSVER2ENA | - OSI_MAC_TCR_TSIPENA); - - if (pto_config->snap_type > 0U) { - /* Set APDREQEN bit if snap_type > 0 */ - ptc_value |= MGBE_MAC_PTO_CR_APDREQEN; - } - - /* Set SNAPTYPSEL for Taking Snapshots mode */ - value |= ((pto_config->snap_type << MGBE_MAC_TCR_SNAPTYPSEL_SHIFT) & - OSI_MAC_TCR_SNAPTYPSEL_3); - /* Set/Reset TSMSTRENA bit for Master/Slave */ - if (pto_config->master == OSI_ENABLE) { - /* Set TSMSTRENA bit for master */ - value |= OSI_MAC_TCR_TSMASTERENA; - if (pto_config->snap_type != OSI_PTP_SNAP_P2P) { - /* Set ASYNCEN bit on PTO Control Register */ - ptc_value |= MGBE_MAC_PTO_CR_ASYNCEN; - } - } else { - /* Reset TSMSTRENA bit for slave */ - value &= ~OSI_MAC_TCR_TSMASTERENA; - } - - /* Set/Reset TSENMACADDR bit for UC/MC MAC */ - if (pto_config->mc_uc == OSI_ENABLE) { - /* Set TSENMACADDR bit for MC/UC MAC PTP filter */ - value |= MGBE_MAC_TCR_TSENMACADDR; - } else { - /* Reset TSENMACADDR bit */ - value &= ~MGBE_MAC_TCR_TSENMACADDR; - } - - /* Set TSEVNTENA bit for PTP events */ - value |= OSI_MAC_TCR_TSEVENTENA; - - /* update global setting in ptp_filter */ - osi_core->ptp_config.ptp_filter = value; - /** Write PTO_CR and TCR registers */ - osi_writela(osi_core, ptc_value, addr + MGBE_MAC_PTO_CR); - osi_writela(osi_core, value, addr + MGBE_MAC_TCR); - /* Port ID for PTP offload packet created */ - port_id = pto_config->portid & MGBE_MAC_PIDR_PID_MASK; - osi_writela(osi_core, port_id, addr + MGBE_MAC_PIDR0); - osi_writela(osi_core, OSI_NONE, addr + MGBE_MAC_PIDR1); - osi_writela(osi_core, OSI_NONE, addr + MGBE_MAC_PIDR2); - - return ret; -} - -#ifdef HSI_SUPPORT -/** - * @brief mgbe_handle_hsi_intr - Handles hsi interrupt. - * - * Algorithm: - * - Read safety interrupt status register and clear it. - * - Update error code in osi_hsi_data structure - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_handle_hsi_intr(struct osi_core_priv_data *osi_core) -{ - nveu32_t val = 0; - nveu32_t val2 = 0; - void *xpcs_base = osi_core->xpcs_base; - nveu64_t ce_count_threshold; - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_STATUS); - if (((val & MGBE_REGISTER_PARITY_ERR) == MGBE_REGISTER_PARITY_ERR) || - ((val & MGBE_CORE_UNCORRECTABLE_ERR) == MGBE_CORE_UNCORRECTABLE_ERR)) { - osi_core->hsi.err_code[UE_IDX] = - hsi_err_code[osi_core->instance_id][UE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.report_count_err[UE_IDX] = OSI_ENABLE; - /* Disable the interrupt */ - val2 = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - val2 &= ~MGBE_REGISTER_PARITY_ERR; - val2 &= ~MGBE_CORE_UNCORRECTABLE_ERR; - osi_writela(osi_core, val2, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - } - if ((val & MGBE_CORE_CORRECTABLE_ERR) == MGBE_CORE_CORRECTABLE_ERR) { - osi_core->hsi.err_code[CE_IDX] = - hsi_err_code[osi_core->instance_id][CE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.ce_count = - osi_update_stats_counter(osi_core->hsi.ce_count, 1UL); - ce_count_threshold = osi_core->hsi.ce_count / osi_core->hsi.err_count_threshold; - if (osi_core->hsi.ce_count_threshold < ce_count_threshold) { - osi_core->hsi.ce_count_threshold = ce_count_threshold; - osi_core->hsi.report_count_err[CE_IDX] = OSI_ENABLE; - } - } - val &= ~MGBE_MAC_SBD_INTR; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_WRAP_COMMON_INTR_STATUS); - - if (((val & MGBE_CORE_CORRECTABLE_ERR) == MGBE_CORE_CORRECTABLE_ERR) || - ((val & MGBE_CORE_UNCORRECTABLE_ERR) == MGBE_CORE_UNCORRECTABLE_ERR)) { - /* Clear status register for FSM errors. Clear on read*/ - (void)osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_DPP_FSM_INTERRUPT_STATUS); - - /* Clear status register for ECC error */ - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_ECC_INTERRUPT_STATUS); - if (val != 0U) { - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MTL_ECC_INTERRUPT_STATUS); - } - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_DMA_ECC_INTERRUPT_STATUS); - if (val != 0U) { - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_DMA_ECC_INTERRUPT_STATUS); - } - } - - val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_STATUS); - if (((val & XPCS_CORE_UNCORRECTABLE_ERR) == XPCS_CORE_UNCORRECTABLE_ERR) || - ((val & XPCS_REGISTER_PARITY_ERR) == XPCS_REGISTER_PARITY_ERR)) { - osi_core->hsi.err_code[UE_IDX] = hsi_err_code[osi_core->instance_id][UE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.report_count_err[UE_IDX] = OSI_ENABLE; - /* Disable uncorrectable interrupts */ - val2 = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - val2 &= ~XPCS_CORE_UNCORRECTABLE_ERR; - val2 &= ~XPCS_REGISTER_PARITY_ERR; - osi_writela(osi_core, val2, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_CONTROL); - } - if ((val & XPCS_CORE_CORRECTABLE_ERR) == XPCS_CORE_CORRECTABLE_ERR) { - osi_core->hsi.err_code[CE_IDX] = hsi_err_code[osi_core->instance_id][CE_IDX]; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.ce_count = - osi_update_stats_counter(osi_core->hsi.ce_count, 1UL); - ce_count_threshold = osi_core->hsi.ce_count / osi_core->hsi.err_count_threshold; - if (osi_core->hsi.ce_count_threshold < ce_count_threshold) { - osi_core->hsi.ce_count_threshold = ce_count_threshold; - osi_core->hsi.report_count_err[CE_IDX] = OSI_ENABLE; - } - } - - osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_INTERRUPT_STATUS); - - if (((val & XPCS_CORE_CORRECTABLE_ERR) == XPCS_CORE_CORRECTABLE_ERR) || - ((val & XPCS_CORE_UNCORRECTABLE_ERR) == XPCS_CORE_UNCORRECTABLE_ERR)) { - /* Clear status register for PCS error */ - val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_SFTY_UE_INTR0); - if (val != 0U) { - (void)xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_SFTY_UE_INTR0, 0); - } - val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_SFTY_CE_INTR); - if (val != 0U) { - (void)xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_SFTY_CE_INTR, 0); - } - } -} -#endif - -/** - * @brief mgbe_handle_common_intr - Handles common interrupt. - * - * Algorithm: Clear common nve32_terrupt source. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_handle_common_intr(struct osi_core_priv_data *osi_core) -{ - void *base = osi_core->base; - unsigned int dma_isr = 0; - unsigned int qinx = 0; - unsigned int i = 0; - unsigned int dma_sr = 0; - unsigned int dma_ier = 0; - unsigned int mtl_isr = 0; - unsigned int val = 0; - -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - mgbe_handle_hsi_intr(osi_core); - } -#endif - dma_isr = osi_readla(osi_core, (nveu8_t *)base + MGBE_DMA_ISR); - if (dma_isr == OSI_NONE) { - return; - } - - //FIXME Need to check how we can get the DMA channel here instead of - //MTL Queues - if ((dma_isr & MGBE_DMA_ISR_DCH0_DCH15_MASK) != OSI_NONE) { - /* Handle Non-TI/RI nve32_terrupts */ - for (i = 0; i < osi_core->num_mtl_queues; i++) { - qinx = osi_core->mtl_queues[i]; - - if (qinx >= OSI_MGBE_MAX_NUM_CHANS) { - continue; - } - - /* read dma channel status register */ - dma_sr = osi_readla(osi_core, (nveu8_t *)base + - MGBE_DMA_CHX_STATUS(qinx)); - /* read dma channel nve32_terrupt enable register */ - dma_ier = osi_readla(osi_core, (nveu8_t *)base + - MGBE_DMA_CHX_IER(qinx)); - - /* process only those nve32_terrupts which we - * have enabled. - */ - dma_sr = (dma_sr & dma_ier); - - /* mask off RI and TI */ - dma_sr &= ~(MGBE_DMA_CHX_STATUS_TI | - MGBE_DMA_CHX_STATUS_RI); - if (dma_sr == OSI_NONE) { - continue; - } - - /* ack non ti/ri nve32_ts */ - osi_writela(osi_core, dma_sr, (nveu8_t *)base + - MGBE_DMA_CHX_STATUS(qinx)); - mgbe_update_dma_sr_stats(osi_core, dma_sr, qinx); - } - } - - mgbe_handle_mac_intrs(osi_core, dma_isr); - - /* Handle MTL inerrupts */ - mtl_isr = osi_readla(osi_core, - (unsigned char *)base + MGBE_MTL_INTR_STATUS); - if ((dma_isr & MGBE_DMA_ISR_MTLIS) == MGBE_DMA_ISR_MTLIS) { - mgbe_handle_mtl_intrs(osi_core, mtl_isr); - } - - /* Clear common interrupt status in wrapper register */ - osi_writela(osi_core, MGBE_MAC_SBD_INTR, - (unsigned char *)base + MGBE_WRAP_COMMON_INTR_STATUS); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - val |= MGBE_MAC_SBD_INTR; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_WRAP_COMMON_INTR_ENABLE); - - /* Clear FRP Interrupts in MTL_RXP_Interrupt_Control_Status */ - val = osi_readla(osi_core, (nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); - val |= (MGBE_MTL_RXP_INTR_CS_NVEOVIS | - MGBE_MTL_RXP_INTR_CS_NPEOVIS | - MGBE_MTL_RXP_INTR_CS_FOOVIS | - MGBE_MTL_RXP_INTR_CS_PDRFIS); - osi_writela(osi_core, val, (nveu8_t *)base + MGBE_MTL_RXP_INTR_CS); -} - -/** - * @brief mgbe_pad_calibrate - PAD calibration - * - * Algorithm: Since PAD calibration not applicable for MGBE - * it returns zero. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval zero always - */ -static nve32_t mgbe_pad_calibrate(OSI_UNUSED - struct osi_core_priv_data *const osi_core) -{ - return 0; -} - -/** - * @brief mgbe_start_mac - Start MAC Tx/Rx engine - * - * Algorithm: Enable MAC Transmitter and Receiver - * - * @param[in] osi_core: OSI core private data structure. - * - * @note 1) MAC init should be complete. See osi_hw_core_init() and - * osi_hw_dma_init() - */ -static void mgbe_start_mac(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - void *addr = osi_core->base; - - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); - /* Enable MAC Transmit */ - value |= MGBE_MAC_TMCR_TE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_RMCR); - /* Enable MAC Receive */ - value |= MGBE_MAC_RMCR_RE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_RMCR); -} - -/** - * @brief mgbe_stop_mac - Stop MAC Tx/Rx engine - * - * Algorithm: Disables MAC Transmitter and Receiver - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC DMA deinit should be complete. See osi_hw_dma_deinit() - */ -static void mgbe_stop_mac(struct osi_core_priv_data *const osi_core) -{ - nveu32_t value; - void *addr = osi_core->base; - - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); - /* Disable MAC Transmit */ - value &= ~MGBE_MAC_TMCR_TE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_RMCR); - /* Disable MAC Receive */ - value &= ~MGBE_MAC_RMCR_RE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_RMCR); -} - -#ifdef MACSEC_SUPPORT -/** - * @brief mgbe_config_mac_tx - Enable/Disable MAC Tx - * - * Algorithm: Enable/Disable MAC Transmitter engine - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] enable: Enable or Disable.MAC Tx - * - * @note 1) MAC init should be complete. See osi_hw_core_init() - */ -static void mgbe_config_mac_tx(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value; - void *addr = osi_core->base; - - if (enable == OSI_ENABLE) { - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); - /* Enable MAC Transmit */ - value |= MGBE_MAC_TMCR_TE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - } else { - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_TMCR); - /* Disable MAC Transmit */ - value &= ~MGBE_MAC_TMCR_TE; - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_TMCR); - } -} -#endif /* MACSEC_SUPPORT */ - -/** - * @brief mgbe_core_deinit - MGBE MAC core deinitialization - * - * Algorithm: This function will take care of deinitializing MAC - * - * @param[in] osi_core: OSI core private data structure. - * - * @note Required clks and resets has to be enabled - */ -static void mgbe_core_deinit(struct osi_core_priv_data *osi_core) -{ - /* Stop the MAC by disabling both MAC Tx and Rx */ - mgbe_stop_mac(osi_core); -} - -/** - * @brief mgbe_set_speed - Set operating speed - * - * Algorithm: Based on the speed (2.5G/5G/10G) MAC will be configured - * accordingly. - * - * @param[in] osi_core: OSI core private data. - * @param[in] speed: Operating speed. - * - * @note MAC should be init and started. see osi_start_mac() - */ -static int mgbe_set_speed(struct osi_core_priv_data *const osi_core, - const int speed) -{ - unsigned int value = 0; - - value = osi_readla(osi_core, - (unsigned char *) osi_core->base + MGBE_MAC_TMCR); - - switch (speed) { - case OSI_SPEED_2500: - value |= MGBE_MAC_TMCR_SS_2_5G; - break; - case OSI_SPEED_5000: - value |= MGBE_MAC_TMCR_SS_5G; - break; - case OSI_SPEED_10000: - value &= ~MGBE_MAC_TMCR_SS_10G; - break; - default: - /* setting default to 10G */ - value &= ~MGBE_MAC_TMCR_SS_10G; - break; - } - - osi_writela(osi_core, value, (unsigned char *) - osi_core->base + MGBE_MAC_TMCR); - - if (xpcs_init(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "xpcs_init failed\n", OSI_NONE); - return -1; - } - - return xpcs_start(osi_core); -} - -/** - * @brief mgbe_mdio_busy_wait - MDIO busy wait loop - * - * Algorithm: Wait for any previous MII read/write operation to complete - * - * @param[in] osi_core: OSI core data struture. - */ -static int mgbe_mdio_busy_wait(struct osi_core_priv_data *const osi_core) -{ - /* half second timeout */ - unsigned int retry = 50000; - unsigned int mac_gmiiar; - unsigned int count; - int cond = 1; - - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - - mac_gmiiar = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCD); - if ((mac_gmiiar & MGBE_MDIO_SCCD_SBUSY) == 0U) { - cond = 0; - } else { - osi_core->osd_ops.udelay(10U); - } - } - - return 0; -} - -/* - * @brief mgbe_save_registers Function to store a backup of - * MAC register space during SOC suspend. - * - * Algorithm: Read registers to be backed up as per struct core_backup and - * store the register values in memory. - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_save_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int i = 0; - struct core_backup *config = &osi_core->backup_config; - int ret = 0; - - /* Save direct access registers */ - for (i = 0; i < MGBE_DIRECT_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - /* Read the register and store into reg_val */ - config->reg_val[i] = osi_readla(osi_core, - config->reg_addr[i]); - } - } - - /* Save L3 and L4 indirect addressing registers */ - for (i = 0; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L3L4_CTR, - &config->reg_val[MGBE_MAC_L3L4_CTR_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3L4_CTR read fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L4_ADDR, - &config->reg_val[MGBE_MAC_L4_ADR_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L4_ADDR read fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L3_AD0R, - &config->reg_val[MGBE_MAC_L3_AD0R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD0R read fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L3_AD1R, - &config->reg_val[MGBE_MAC_L3_AD1R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD1R read fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L3_AD2R, - &config->reg_val[MGBE_MAC_L3_AD2R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD2R read fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_read(osi_core, i, MGBE_MAC_L3_AD3R, - &config->reg_val[MGBE_MAC_L3_AD3R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD3R read fail return here */ - return ret; - } - } - - /* Save MAC_DChSel_IndReg indirect addressing registers */ - for (i = 0; i < OSI_MGBE_MAX_MAC_ADDRESS_FILTER; i++) { - ret = mgbe_mac_indir_addr_read(osi_core, MGBE_MAC_DCHSEL, - i, &config->reg_val[MGBE_MAC_DCHSEL_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_DCHSEL read fail return here */ - return ret; - } - } - - return ret; -} - -/** - * @brief mgbe_restore_registers Function to restore the backup of - * MAC registers during SOC resume. - * - * Algorithm: Restore the register values from the in memory backup taken using - * mgbe_save_registers(). - * - * @param[in] osi_core: OSI core private data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_restore_registers( - struct osi_core_priv_data *const osi_core) -{ - unsigned int i = 0; - struct core_backup *config = &osi_core->backup_config; - int ret = 0; - - /* Restore direct access registers */ - for (i = 0; i < MGBE_MAX_BAK_IDX; i++) { - if (config->reg_addr[i] != OSI_NULL) { - /* Write back the saved register value */ - osi_writela(osi_core, config->reg_val[i], - config->reg_addr[i]); - } - } - - /* Restore L3 and L4 indirect addressing registers */ - for (i = 0; i < OSI_MGBE_MAX_L3_L4_FILTER; i++) { - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L3L4_CTR, - config->reg_val[MGBE_MAC_L3L4_CTR_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3L4_CTR write fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L4_ADDR, - config->reg_val[MGBE_MAC_L4_ADR_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L4_ADDR write fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L3_AD0R, - config->reg_val[MGBE_MAC_L3_AD0R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD0R write fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L3_AD1R, - config->reg_val[MGBE_MAC_L3_AD1R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD1R write fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L3_AD2R, - config->reg_val[MGBE_MAC_L3_AD2R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD2R write fail return here */ - return ret; - } - ret = mgbe_l3l4_filter_write(osi_core, i, MGBE_MAC_L3_AD3R, - config->reg_val[MGBE_MAC_L3_AD3R_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_L3_AD3R write fail return here */ - return ret; - } - } - - /* Restore MAC_DChSel_IndReg indirect addressing registers */ - for (i = 0; i < OSI_MGBE_MAX_MAC_ADDRESS_FILTER; i++) { - ret = mgbe_mac_indir_addr_write(osi_core, MGBE_MAC_DCHSEL, - i, config->reg_val[MGBE_MAC_DCHSEL_BAK_IDX(i)]); - if (ret < 0) { - /* MGBE_MAC_DCHSEL write fail return here */ - return ret; - } - } - - return ret; -} - -/** - * @brief mgbe_write_phy_reg - Write to a PHY register over MDIO bus. - * - * Algorithm: Write into a PHY register through MGBE MDIO bus. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be write to PHY. - * @param[in] phydata: Data to write to a PHY register. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_write_phy_reg(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg, - unsigned short phydata) -{ - int ret = 0; - unsigned int reg; - - /* Wait for any previous MII read/write operation to complete */ - ret = mgbe_mdio_busy_wait(osi_core); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); - return ret; - } - - /* set MDIO address register */ - /* set device address */ - reg = ((phyreg >> MGBE_MDIO_C45_DA_SHIFT) & MGBE_MDIO_SCCA_DA_MASK) << - MGBE_MDIO_SCCA_DA_SHIFT; - /* set port address and register address */ - reg |= (phyaddr << MGBE_MDIO_SCCA_PA_SHIFT) | - (phyreg & MGBE_MDIO_SCCA_RA_MASK); - osi_writela(osi_core, reg, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCA); - - /* Program Data register */ - reg = phydata | - (MGBE_MDIO_SCCD_CMD_WR << MGBE_MDIO_SCCD_CMD_SHIFT) | - MGBE_MDIO_SCCD_SBUSY; - - /** - * On FPGA AXI/APB clock is 13MHz. To achive maximum MDC clock - * of 2.5MHz need to enable CRS and CR to be set to 1. - * On Silicon AXI/APB clock is 408MHz. To achive maximum MDC clock - * of 2.5MHz only CR need to be set to 5. - */ - if (osi_core->pre_si) { - reg |= (MGBE_MDIO_SCCD_CRS | - ((0x1U & MGBE_MDIO_SCCD_CR_MASK) << - MGBE_MDIO_SCCD_CR_SHIFT)); - } else { - reg &= ~MGBE_MDIO_SCCD_CRS; - reg |= ((0x5U & MGBE_MDIO_SCCD_CR_MASK) << - MGBE_MDIO_SCCD_CR_SHIFT); - } - - osi_writela(osi_core, reg, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCD); - - /* wait for MII write operation to complete */ - ret = mgbe_mdio_busy_wait(osi_core); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); - return ret; - } - - return 0; -} - -/** - * @brief mgbe_read_phy_reg - Read from a PHY register over MDIO bus. - * - * Algorithm: Write into a PHY register through MGBE MDIO bus. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] phyaddr: PHY address (PHY ID) associated with PHY - * @param[in] phyreg: Register which needs to be read from PHY. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_read_phy_reg(struct osi_core_priv_data *osi_core, - unsigned int phyaddr, - unsigned int phyreg) -{ - unsigned int reg; - unsigned int data; - int ret = 0; - - ret = mgbe_mdio_busy_wait(osi_core); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); - return ret; - } - - /* set MDIO address register */ - /* set device address */ - reg = ((phyreg >> MGBE_MDIO_C45_DA_SHIFT) & MGBE_MDIO_SCCA_DA_MASK) << - MGBE_MDIO_SCCA_DA_SHIFT; - /* set port address and register address */ - reg |= (phyaddr << MGBE_MDIO_SCCA_PA_SHIFT) | - (phyreg & MGBE_MDIO_SCCA_RA_MASK); - osi_writela(osi_core, reg, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCA); - - /* Program Data register */ - reg = (MGBE_MDIO_SCCD_CMD_RD << MGBE_MDIO_SCCD_CMD_SHIFT) | - MGBE_MDIO_SCCD_SBUSY; - - /** - * On FPGA AXI/APB clock is 13MHz. To achive maximum MDC clock - * of 2.5MHz need to enable CRS and CR to be set to 1. - * On Silicon AXI/APB clock is 408MHz. To achive maximum MDC clock - * of 2.5MHz only CR need to be set to 5. - */ - if (osi_core->pre_si) { - reg |= (MGBE_MDIO_SCCD_CRS | - ((0x1U & MGBE_MDIO_SCCD_CR_MASK) << - MGBE_MDIO_SCCD_CR_SHIFT)); - } else { - reg &= ~MGBE_MDIO_SCCD_CRS; - reg |= ((0x5U & MGBE_MDIO_SCCD_CR_MASK) << - MGBE_MDIO_SCCD_CR_SHIFT); - } - - osi_writela(osi_core, reg, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCD); - - ret = mgbe_mdio_busy_wait(osi_core); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, - "MII operation timed out\n", - 0ULL); - return ret; - } - - reg = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MDIO_SCCD); - - data = (reg & MGBE_MDIO_SCCD_SDATA_MASK); - return (int)data; -} - -/** - * @brief mgbe_hw_est_write - indirect write the GCL to Software own list - * (SWOL) - * - * @param[in] base: MAC base IOVA address. - * @param[in] addr_val: Address offset for indirect write. - * @param[in] data: Data to be written at offset. - * @param[in] gcla: Gate Control List Address, 0 for ETS register. - * 1 for GCL memory. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_hw_est_write(struct osi_core_priv_data *osi_core, - unsigned int addr_val, unsigned int data, - unsigned int gcla) -{ - int retry = 1000; - unsigned int val = 0x0; - - osi_writela(osi_core, data, (unsigned char *)osi_core->base + - MGBE_MTL_EST_DATA); - - val &= ~MGBE_MTL_EST_ADDR_MASK; - val |= (gcla == 1U) ? 0x0U : MGBE_MTL_EST_GCRR; - val |= MGBE_MTL_EST_SRWO; - val |= addr_val; - osi_writela(osi_core, val, (unsigned char *)osi_core->base + - MGBE_MTL_EST_GCL_CONTROL); - - while (--retry > 0) { - osi_core->osd_ops.udelay(OSI_DELAY_1US); - val = osi_readla(osi_core, (unsigned char *)osi_core->base + - MGBE_MTL_EST_GCL_CONTROL); - if ((val & MGBE_MTL_EST_SRWO) == MGBE_MTL_EST_SRWO) { - continue; - } - - break; - } - - if ((val & MGBE_MTL_EST_ERR0) == MGBE_MTL_EST_ERR0 || - (retry <= 0)) { - return -1; - } - - return 0; -} - -/** - * @brief mgbe_hw_config_est - Read Setting for GCL from input and update - * registers. - * - * Algorithm: - * 1) Write TER, LLR and EST control register - * 2) Update GCL to sw own GCL (MTL_EST_Status bit SWOL will tell which is - * owned by SW) and store which GCL is in use currently in sw. - * 3) TODO set DBGB and DBGM for debugging - * 4) EST_data and GCRR to 1, update entry sno in ADDR and put data at - * est_gcl_data enable GCL MTL_EST_SSWL and wait for self clear or use - * SWLC in MTL_EST_Status. Please note new GCL will be pushed for each entry. - * 5) Configure btr. Update btr based on current time (current time - * should be updated based on PTP by this time) - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est: EST configuration input argument. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_hw_config_est(struct osi_core_priv_data *osi_core, - struct osi_est_config *est) -{ - unsigned int btr[2] = {0}; - unsigned int val = 0x0; - void *base = osi_core->base; - unsigned int i; - int ret = 0; - unsigned int addr = 0x0; - - if ((osi_core->hw_feature != OSI_NULL) && - (osi_core->hw_feature->est_sel == OSI_DISABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "EST not supported in HW\n", 0ULL); - return -1; - } - - if (est->en_dis == OSI_DISABLE) { - val = osi_readla(osi_core, (unsigned char *) - base + MGBE_MTL_EST_CONTROL); - val &= ~MGBE_MTL_EST_EEST; - osi_writela(osi_core, val, (unsigned char *) - base + MGBE_MTL_EST_CONTROL); - - return 0; - } - - btr[0] = est->btr[0]; - btr[1] = est->btr[1]; - if (btr[0] == 0U && btr[1] == 0U) { - common_get_systime_from_mac(osi_core->base, - osi_core->mac, - &btr[1], &btr[0]); - } - - if (gcl_validate(osi_core, est, btr, osi_core->mac) < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL validation failed\n", 0LL); - return -1; - } - - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_CTR_LOW, est->ctr[0], 0); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL CTR[0] failed\n", 0LL); - return ret; - } - /* check for est->ctr[i] not more than FF, TODO as per hw config - * parameter we can have max 0x3 as this value in sec */ - est->ctr[1] &= MGBE_MTL_EST_CTR_HIGH_MAX; - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_CTR_HIGH, est->ctr[1], 0); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL CTR[1] failed\n", 0LL); - return ret; - } - - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_TER, est->ter, 0); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL TER failed\n", 0LL); - return ret; - } - - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_LLR, est->llr, 0); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL LLR failed\n", 0LL); - return ret; - } - - /* Write GCL table */ - for (i = 0U; i < est->llr; i++) { - addr = i; - addr = addr << MGBE_MTL_EST_ADDR_SHIFT; - addr &= MGBE_MTL_EST_ADDR_MASK; - ret = mgbe_hw_est_write(osi_core, addr, est->gcl[i], 1); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL enties write failed\n", - (unsigned long long)i); - return ret; - } - } - - /* Write parameters */ - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_BTR_LOW, - btr[0] + est->btr_offset[0], OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL BTR[0] failed\n", - (unsigned long long)(btr[0] + - est->btr_offset[0])); - return ret; - } - - ret = mgbe_hw_est_write(osi_core, MGBE_MTL_EST_BTR_HIGH, - btr[1] + est->btr_offset[1], OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "GCL BTR[1] failed\n", - (unsigned long long)(btr[1] + - est->btr_offset[1])); - return ret; - } - - val = osi_readla(osi_core, (unsigned char *) - base + MGBE_MTL_EST_CONTROL); - /* Store table */ - val |= MGBE_MTL_EST_SSWL; - val |= MGBE_MTL_EST_EEST; - val |= MGBE_MTL_EST_QHLBF; - osi_writela(osi_core, val, (unsigned char *) - base + MGBE_MTL_EST_CONTROL); - - return ret; -} - -/** - * @brief mgbe_hw_config_fep - Read Setting for preemption and express for TC - * and update registers. - * - * Algorithm: - * 1) Check for TC enable and TC has masked for setting to preemptable. - * 2) update FPE control status register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] fpe: FPE configuration input argument. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_hw_config_fpe(struct osi_core_priv_data *osi_core, - struct osi_fpe_config *fpe) -{ - unsigned int i = 0U; - unsigned int val = 0U; - unsigned int temp = 0U, temp1 = 0U; - unsigned int temp_shift = 0U; - int ret = 0; - - if ((osi_core->hw_feature != OSI_NULL) && - (osi_core->hw_feature->fpe_sel == OSI_DISABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "FPE not supported in HW\n", 0ULL); - return -1; - } - -#ifdef MACSEC_SUPPORT - osi_lock_irq_enabled(&osi_core->macsec_fpe_lock); - /* MACSEC and FPE cannot coexist on MGBE refer bug 3484034 */ - if (osi_core->is_macsec_enabled == OSI_ENABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "FPE and MACSEC cannot co-exist\n", 0ULL); - ret = -1; - goto exit; - } -#endif /* MACSEC_SUPPORT */ - - osi_core->fpe_ready = OSI_DISABLE; - - if (((fpe->tx_queue_preemption_enable << MGBE_MTL_FPE_CTS_PEC_SHIFT) & - MGBE_MTL_FPE_CTS_PEC) == OSI_DISABLE) { - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_FPE_CTS); - val &= ~MGBE_MTL_FPE_CTS_PEC; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MTL_FPE_CTS); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_FPE_CTS); - val &= ~MGBE_MAC_FPE_CTS_EFPE; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MAC_FPE_CTS); - -#ifdef MACSEC_SUPPORT - osi_core->is_fpe_enabled = OSI_DISABLE; -#endif /* MACSEC_SUPPORT */ - ret = 0; - goto exit; - } - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MTL_FPE_CTS); - val &= ~MGBE_MTL_FPE_CTS_PEC; - for (i = 0U; i < OSI_MAX_TC_NUM; i++) { - /* max 8 bit for this structure fot TC/TXQ. Set the TC for express or - * preemption. Default is express for a TC. DWCXG_NUM_TC = 8 */ - temp = OSI_BIT(i); - if ((fpe->tx_queue_preemption_enable & temp) == temp) { - temp_shift = i; - temp_shift += MGBE_MTL_FPE_CTS_PEC_SHIFT; - /* set queue for preemtable */ - if (temp_shift < MGBE_MTL_FPE_CTS_PEC_MAX_SHIFT) { - temp1 = OSI_ENABLE; - temp1 = temp1 << temp_shift; - val |= temp1; - } else { - /* Do nothing */ - } - } - } - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + - MGBE_MTL_FPE_CTS); - - if (fpe->rq == 0x0U || fpe->rq >= OSI_MGBE_MAX_NUM_CHANS) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "FPE init failed due to wrong RQ\n", fpe->rq); - ret = -1; - goto exit; - } - - val = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_RQC1R); - val &= ~MGBE_MAC_RQC1R_RQ; - temp = fpe->rq; - temp = temp << MGBE_MAC_RQC1R_RQ_SHIFT; - temp = (temp & MGBE_MAC_RQC1R_RQ); - val |= temp; - osi_core->residual_queue = fpe->rq; - osi_writela(osi_core, val, (unsigned char *) - osi_core->base + MGBE_MAC_RQC1R); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); - val &= ~MGBE_MAC_RQC4R_PMCBCQ; - temp = fpe->rq; - temp = temp << MGBE_MAC_RQC4R_PMCBCQ_SHIFT; - temp = (temp & MGBE_MAC_RQC4R_PMCBCQ); - val |= temp; - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + MGBE_MAC_RQC4R); - - /* initiate SVER for SMD-V and SMD-R */ - val = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MTL_FPE_CTS); - val |= MGBE_MAC_FPE_CTS_SVER; - osi_writela(osi_core, val, (unsigned char *) - osi_core->base + MGBE_MAC_FPE_CTS); - - val = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MTL_FPE_ADV); - val &= ~MGBE_MTL_FPE_ADV_HADV_MASK; - //(minimum_fragment_size +IPG/EIPG + Preamble) *.8 ~98ns for10G - val |= MGBE_MTL_FPE_ADV_HADV_VAL; - osi_writela(osi_core, val, (unsigned char *) - osi_core->base + MGBE_MTL_FPE_ADV); - -#ifdef MACSEC_SUPPORT - osi_core->is_fpe_enabled = OSI_ENABLE; -#endif /* MACSEC_SUPPORT */ - -exit: - -#ifdef MACSEC_SUPPORT - osi_unlock_irq_enabled(&osi_core->macsec_fpe_lock); -#endif /* MACSEC_SUPPORT */ - return ret; -} - -/** - * @brief mgbe_disable_tx_lpi - Helper function to disable Tx LPI. - * - * Algorithm: - * Clear the bits to enable Tx LPI, Tx LPI automate, LPI Tx Timer and - * PHY Link status in the LPI control/status register - * - * @param[in] osi_core: OSI core private data structure. - * - * @note MAC has to be out of reset, and clocks supplied. - */ -static inline void mgbe_disable_tx_lpi(struct osi_core_priv_data *osi_core) -{ - unsigned int lpi_csr = 0; - - /* Disable LPI control bits */ - lpi_csr = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_LPI_CSR); - lpi_csr &= ~(MGBE_MAC_LPI_CSR_LPITE | MGBE_MAC_LPI_CSR_LPITXA | - MGBE_MAC_LPI_CSR_PLS | MGBE_MAC_LPI_CSR_LPIEN); - osi_writela(osi_core, lpi_csr, (unsigned char *) - osi_core->base + MGBE_MAC_LPI_CSR); -} - -/** - * @brief mgbe_configure_eee - Configure the EEE LPI mode - * - * Algorithm: This routine configures EEE LPI mode in the MAC. - * 1) The time (in microsecond) to wait before resuming transmission after - * exiting from LPI - * 2) The time (in millisecond) to wait before LPI pattern can be transmitted - * after PHY link is up) are not configurable. Default values are used in this - * routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_lpi_enable: enable (1)/disable (0) flag for Tx lpi - * @param[in] tx_lpi_timer: Tx LPI entry timer in usec. Valid upto - * OSI_MAX_TX_LPI_TIMER in steps of 8usec. - * - * @note Required clks and resets has to be enabled. - * MAC/PHY should be initialized - * - */ -static void mgbe_configure_eee(struct osi_core_priv_data *osi_core, - unsigned int tx_lpi_enabled, - unsigned int tx_lpi_timer) -{ - unsigned int lpi_csr = 0; - unsigned int lpi_timer_ctrl = 0; - unsigned int lpi_entry_timer = 0; - unsigned int tic_counter = 0; - void *addr = osi_core->base; - - if (xpcs_eee(osi_core, tx_lpi_enabled) != 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "xpcs_eee call failed\n", 0ULL); - return; - } - - if (tx_lpi_enabled != OSI_DISABLE) { - /** 3. Program LST (bits[25:16]) and TWT (bits[15:0]) in - * MAC_LPI_Timers_Control Register - * Configure the following timers. - * a. LPI LS timer - minimum time (in milliseconds) for - * which the link status from PHY should be up before - * the LPI pattern can be transmitted to the PHY. Default - * 1sec - * b. LPI TW timer - minimum time (in microseconds) for which - * MAC waits after it stops transmitting LPI pattern before - * resuming normal tx. Default 21us - */ - - lpi_timer_ctrl |= ((MGBE_DEFAULT_LPI_LS_TIMER << - MGBE_LPI_LS_TIMER_SHIFT) & - MGBE_LPI_LS_TIMER_MASK); - lpi_timer_ctrl |= (MGBE_DEFAULT_LPI_TW_TIMER & - MGBE_LPI_TW_TIMER_MASK); - osi_writela(osi_core, lpi_timer_ctrl, (unsigned char *)addr + - MGBE_MAC_LPI_TIMER_CTRL); - - /* 4. For GMII, read the link status of the PHY chip by - * using the MDIO interface and update Bit 17 of - * MAC_LPI_Control_Status register accordingly. This update - * should be done whenever the link status in the PHY chip - * changes. For XGMII, the update is automatic unless - * PLSDIS bit is set." (skip) */ - /* 5. Program the MAC_1US_Tic_Counter as per the frequency - * of the clock used for accessing the CSR slave port. - */ - /* Should be same as (ABP clock freq - 1) = 12 = 0xC, currently - * from define but we should get it from pdata->clock TODO */ - tic_counter = MGBE_1US_TIC_COUNTER; - osi_writela(osi_core, tic_counter, (unsigned char *)addr + - MGBE_MAC_1US_TIC_COUNT); - - /* 6. Program the MAC_LPI_Auto_Entry_Timer register (LPIET) - * with the IDLE time for which the MAC should wait - * before entering the LPI state on its own. - * LPI entry timer - Time in microseconds that MAC will wait - * to enter LPI mode after all tx is complete. Default 1sec - */ - lpi_entry_timer |= (tx_lpi_timer & MGBE_LPI_ENTRY_TIMER_MASK); - osi_writela(osi_core, lpi_entry_timer, (unsigned char *)addr + - MGBE_MAC_LPI_EN_TIMER); - - /* 7. Set LPIATE and LPITXA (bit[20:19]) of - * MAC_LPI_Control_Status register to enable the auto-entry - * into LPI and auto-exit of MAC from LPI state. - * 8. Set LPITXEN (bit[16]) of MAC_LPI_Control_Status register - * to make the MAC Transmitter enter the LPI state. The MAC - * enters the LPI mode after completing all scheduled - * packets and remain IDLE for the time indicated by LPIET. - */ - lpi_csr = osi_readla(osi_core, (unsigned char *) - addr + MGBE_MAC_LPI_CSR); - lpi_csr |= (MGBE_MAC_LPI_CSR_LPITE | MGBE_MAC_LPI_CSR_LPITXA | - MGBE_MAC_LPI_CSR_PLS | MGBE_MAC_LPI_CSR_LPIEN); - osi_writela(osi_core, lpi_csr, (unsigned char *) - addr + MGBE_MAC_LPI_CSR); - } else { - /* Disable LPI control bits */ - mgbe_disable_tx_lpi(osi_core); - } -} - -static int mgbe_get_hw_features(struct osi_core_priv_data *osi_core, - struct osi_hw_features *hw_feat) -{ - unsigned char *base = (unsigned char *)osi_core->base; - unsigned int mac_hfr0 = 0; - unsigned int mac_hfr1 = 0; - unsigned int mac_hfr2 = 0; - unsigned int mac_hfr3 = 0; - unsigned int val = 0; - - mac_hfr0 = osi_readla(osi_core, base + MGBE_MAC_HFR0); - mac_hfr1 = osi_readla(osi_core, base + MGBE_MAC_HFR1); - mac_hfr2 = osi_readla(osi_core, base + MGBE_MAC_HFR2); - mac_hfr3 = osi_readla(osi_core, base + MGBE_MAC_HFR3); - - hw_feat->rgmii_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_RGMIISEL_SHIFT) & - MGBE_MAC_HFR0_RGMIISEL_MASK); - hw_feat->gmii_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_GMIISEL_SHIFT) & - MGBE_MAC_HFR0_GMIISEL_MASK); - hw_feat->rmii_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_RMIISEL_SHIFT) & - MGBE_MAC_HFR0_RMIISEL_MASK); - hw_feat->hd_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_HDSEL_SHIFT) & - MGBE_MAC_HFR0_HDSEL_MASK); - hw_feat->vlan_hash_en = ((mac_hfr0 >> MGBE_MAC_HFR0_VLHASH_SHIFT) & - MGBE_MAC_HFR0_VLHASH_MASK); - hw_feat->sma_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_SMASEL_SHIFT) & - MGBE_MAC_HFR0_SMASEL_MASK); - hw_feat->rwk_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_RWKSEL_SHIFT) & - MGBE_MAC_HFR0_RWKSEL_MASK); - hw_feat->mgk_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_MGKSEL_SHIFT) & - MGBE_MAC_HFR0_MGKSEL_MASK); - hw_feat->mmc_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_MMCSEL_SHIFT) & - MGBE_MAC_HFR0_MMCSEL_MASK); - hw_feat->arp_offld_en = ((mac_hfr0 >> MGBE_MAC_HFR0_ARPOFFLDEN_SHIFT) & - MGBE_MAC_HFR0_ARPOFFLDEN_MASK); - hw_feat->rav_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_RAVSEL_SHIFT) & - MGBE_MAC_HFR0_RAVSEL_MASK); - hw_feat->av_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_AVSEL_SHIFT) & - MGBE_MAC_HFR0_AVSEL_MASK); - hw_feat->ts_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_TSSSEL_SHIFT) & - MGBE_MAC_HFR0_TSSSEL_MASK); - hw_feat->eee_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_EEESEL_SHIFT) & - MGBE_MAC_HFR0_EEESEL_MASK); - hw_feat->tx_coe_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_TXCOESEL_SHIFT) & - MGBE_MAC_HFR0_TXCOESEL_MASK); - hw_feat->rx_coe_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_RXCOESEL_SHIFT) & - MGBE_MAC_HFR0_RXCOESEL_MASK); - hw_feat->mac_addr_sel = - ((mac_hfr0 >> MGBE_MAC_HFR0_ADDMACADRSEL_SHIFT) & - MGBE_MAC_HFR0_ADDMACADRSEL_MASK); - hw_feat->act_phy_sel = ((mac_hfr0 >> MGBE_MAC_HFR0_PHYSEL_SHIFT) & - MGBE_MAC_HFR0_PHYSEL_MASK); - hw_feat->tsstssel = ((mac_hfr0 >> MGBE_MAC_HFR0_TSSTSSEL_SHIFT) & - MGBE_MAC_HFR0_TSSTSSEL_MASK); - hw_feat->sa_vlan_ins = ((mac_hfr0 >> MGBE_MAC_HFR0_SAVLANINS_SHIFT) & - MGBE_MAC_HFR0_SAVLANINS_SHIFT); - hw_feat->vxn = ((mac_hfr0 >> MGBE_MAC_HFR0_VXN_SHIFT) & - MGBE_MAC_HFR0_VXN_MASK); - hw_feat->ediffc = ((mac_hfr0 >> MGBE_MAC_HFR0_EDIFFC_SHIFT) & - MGBE_MAC_HFR0_EDIFFC_MASK); - hw_feat->edma = ((mac_hfr0 >> MGBE_MAC_HFR0_EDMA_SHIFT) & - MGBE_MAC_HFR0_EDMA_MASK); - hw_feat->rx_fifo_size = ((mac_hfr1 >> MGBE_MAC_HFR1_RXFIFOSIZE_SHIFT) & - MGBE_MAC_HFR1_RXFIFOSIZE_MASK); - hw_feat->pfc_en = ((mac_hfr1 >> MGBE_MAC_HFR1_PFCEN_SHIFT) & - MGBE_MAC_HFR1_PFCEN_MASK); - hw_feat->tx_fifo_size = ((mac_hfr1 >> MGBE_MAC_HFR1_TXFIFOSIZE_SHIFT) & - MGBE_MAC_HFR1_TXFIFOSIZE_MASK); - hw_feat->ost_en = ((mac_hfr1 >> MGBE_MAC_HFR1_OSTEN_SHIFT) & - MGBE_MAC_HFR1_OSTEN_MASK); - hw_feat->pto_en = ((mac_hfr1 >> MGBE_MAC_HFR1_PTOEN_SHIFT) & - MGBE_MAC_HFR1_PTOEN_MASK); - hw_feat->adv_ts_hword = ((mac_hfr1 >> MGBE_MAC_HFR1_ADVTHWORD_SHIFT) & - MGBE_MAC_HFR1_ADVTHWORD_MASK); - hw_feat->addr_64 = ((mac_hfr1 >> MGBE_MAC_HFR1_ADDR64_SHIFT) & - MGBE_MAC_HFR1_ADDR64_MASK); - hw_feat->dcb_en = ((mac_hfr1 >> MGBE_MAC_HFR1_DCBEN_SHIFT) & - MGBE_MAC_HFR1_DCBEN_MASK); - hw_feat->sph_en = ((mac_hfr1 >> MGBE_MAC_HFR1_SPHEN_SHIFT) & - MGBE_MAC_HFR1_SPHEN_MASK); - hw_feat->tso_en = ((mac_hfr1 >> MGBE_MAC_HFR1_TSOEN_SHIFT) & - MGBE_MAC_HFR1_TSOEN_MASK); - hw_feat->dma_debug_gen = ((mac_hfr1 >> MGBE_MAC_HFR1_DBGMEMA_SHIFT) & - MGBE_MAC_HFR1_DBGMEMA_MASK); - hw_feat->rss_en = ((mac_hfr1 >> MGBE_MAC_HFR1_RSSEN_SHIFT) & - MGBE_MAC_HFR1_RSSEN_MASK); - hw_feat->num_tc = ((mac_hfr1 >> MGBE_MAC_HFR1_NUMTC_SHIFT) & - MGBE_MAC_HFR1_NUMTC_MASK); - hw_feat->hash_tbl_sz = ((mac_hfr1 >> MGBE_MAC_HFR1_HASHTBLSZ_SHIFT) & - MGBE_MAC_HFR1_HASHTBLSZ_MASK); - hw_feat->l3l4_filter_num = ((mac_hfr1 >> MGBE_MAC_HFR1_L3L4FNUM_SHIFT) & - MGBE_MAC_HFR1_L3L4FNUM_MASK); - hw_feat->rx_q_cnt = ((mac_hfr2 >> MGBE_MAC_HFR2_RXQCNT_SHIFT) & - MGBE_MAC_HFR2_RXQCNT_MASK); - hw_feat->tx_q_cnt = ((mac_hfr2 >> MGBE_MAC_HFR2_TXQCNT_SHIFT) & - MGBE_MAC_HFR2_TXQCNT_MASK); - hw_feat->rx_ch_cnt = ((mac_hfr2 >> MGBE_MAC_HFR2_RXCHCNT_SHIFT) & - MGBE_MAC_HFR2_RXCHCNT_MASK); - hw_feat->tx_ch_cnt = ((mac_hfr2 >> MGBE_MAC_HFR2_TXCHCNT_SHIFT) & - MGBE_MAC_HFR2_TXCHCNT_MASK); - hw_feat->pps_out_num = ((mac_hfr2 >> MGBE_MAC_HFR2_PPSOUTNUM_SHIFT) & - MGBE_MAC_HFR2_PPSOUTNUM_MASK); - hw_feat->aux_snap_num = ((mac_hfr2 >> MGBE_MAC_HFR2_AUXSNAPNUM_SHIFT) & - MGBE_MAC_HFR2_AUXSNAPNUM_MASK); - hw_feat->num_vlan_filters = ((mac_hfr3 >> MGBE_MAC_HFR3_NRVF_SHIFT) & - MGBE_MAC_HFR3_NRVF_MASK); - hw_feat->frp_sel = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPSEL_SHIFT) & - MGBE_MAC_HFR3_FRPSEL_MASK); - hw_feat->cbti_sel = ((mac_hfr3 >> MGBE_MAC_HFR3_CBTISEL_SHIFT) & - MGBE_MAC_HFR3_CBTISEL_MASK); - hw_feat->num_frp_pipes = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPPIPE_SHIFT) & - MGBE_MAC_HFR3_FRPPIPE_MASK); - hw_feat->ost_over_udp = ((mac_hfr3 >> MGBE_MAC_HFR3_POUOST_SHIFT) & - MGBE_MAC_HFR3_POUOST_MASK); - - val = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPPB_SHIFT) & - MGBE_MAC_HFR3_FRPPB_MASK); - switch (val) { - case MGBE_MAC_FRPPB_64: - hw_feat->max_frp_bytes = MGBE_MAC_FRP_BYTES64; - break; - case MGBE_MAC_FRPPB_128: - hw_feat->max_frp_bytes = MGBE_MAC_FRP_BYTES128; - break; - case MGBE_MAC_FRPPB_256: - default: - hw_feat->max_frp_bytes = MGBE_MAC_FRP_BYTES256; - break; - } - val = ((mac_hfr3 >> MGBE_MAC_HFR3_FRPES_SHIFT) & - MGBE_MAC_HFR3_FRPES_MASK); - switch (val) { - case MGBE_MAC_FRPES_64: - hw_feat->max_frp_entries = MGBE_MAC_FRP_BYTES64; - break; - case MGBE_MAC_FRPES_128: - hw_feat->max_frp_entries = MGBE_MAC_FRP_BYTES128; - break; - case MGBE_MAC_FRPES_256: - default: - hw_feat->max_frp_entries = MGBE_MAC_FRP_BYTES256; - break; - } - - hw_feat->double_vlan_en = ((mac_hfr3 >> MGBE_MAC_HFR3_DVLAN_SHIFT) & - MGBE_MAC_HFR3_DVLAN_MASK); - hw_feat->auto_safety_pkg = ((mac_hfr3 >> MGBE_MAC_HFR3_ASP_SHIFT) & - MGBE_MAC_HFR3_ASP_MASK); - hw_feat->tts_fifo_depth = ((mac_hfr3 >> MGBE_MAC_HFR3_TTSFD_SHIFT) & - MGBE_MAC_HFR3_TTSFD_MASK); - hw_feat->est_sel = ((mac_hfr3 >> MGBE_MAC_HFR3_ESTSEL_SHIFT) & - MGBE_MAC_HFR3_ESTSEL_MASK); - hw_feat->gcl_depth = ((mac_hfr3 >> MGBE_MAC_HFR3_GCLDEP_SHIFT) & - MGBE_MAC_HFR3_GCLDEP_MASK); - hw_feat->gcl_width = ((mac_hfr3 >> MGBE_MAC_HFR3_GCLWID_SHIFT) & - MGBE_MAC_HFR3_GCLWID_MASK); - hw_feat->fpe_sel = ((mac_hfr3 >> MGBE_MAC_HFR3_FPESEL_SHIFT) & - MGBE_MAC_HFR3_FPESEL_MASK); - hw_feat->tbs_sel = ((mac_hfr3 >> MGBE_MAC_HFR3_TBSSEL_SHIFT) & - MGBE_MAC_HFR3_TBSSEL_MASK); - hw_feat->num_tbs_ch = ((mac_hfr3 >> MGBE_MAC_HFR3_TBS_CH_SHIFT) & - MGBE_MAC_HFR3_TBS_CH_MASK); - - return 0; -} - -/** - * @brief mgbe_poll_for_tsinit_complete - Poll for time stamp init complete - * - * Algorithm: Read TSINIT value from MAC TCR register until it is - * equal to zero. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] mac_tcr: Address to store time stamp control register read value - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_poll_for_tsinit_complete( - struct osi_core_priv_data *osi_core, - unsigned int *mac_tcr) -{ - unsigned int retry = 0U; - - while (retry < OSI_POLL_COUNT) { - /* Read and Check TSINIT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_TCR); - if ((*mac_tcr & MGBE_MAC_TCR_TSINIT) == 0U) { - return 0; - } - - retry++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return -1; -} - -/** - * @brief mgbe_set_systime - Set system time - * - * Algorithm: Updates system time (seconds and nano seconds) - * in hardware registers - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] sec: Seconds to be configured - * @param[in] nsec: Nano Seconds to be configured - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_set_systime_to_mac(struct osi_core_priv_data *osi_core, - unsigned int sec, - unsigned int nsec) -{ - unsigned int mac_tcr; - void *addr = osi_core->base; - int ret; - - /* To be sure previous write was flushed (if Any) */ - ret = mgbe_poll_for_tsinit_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (unsigned char *)addr + MGBE_MAC_STSUR); - - /* write nano seconds value to MAC_System_Time_Nanoseconds_Update - * register - */ - osi_writela(osi_core, nsec, (unsigned char *)addr + MGBE_MAC_STNSUR); - - /* issue command to update the configured secs and nsecs values */ - mac_tcr |= MGBE_MAC_TCR_TSINIT; - osi_writela(osi_core, mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); - - ret = mgbe_poll_for_tsinit_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** - * @brief mgbe_poll_for_addend_complete - Poll for addend value write complete - * - * Algorithm: Read TSADDREG value from MAC TCR register until it is - * equal to zero. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] mac_tcr: Address to store time stamp control register read value - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_poll_for_addend_complete( - struct osi_core_priv_data *osi_core, - unsigned int *mac_tcr) -{ - unsigned int retry = 0U; - - /* Poll */ - while (retry < OSI_POLL_COUNT) { - /* Read and Check TSADDREG in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_TCR); - if ((*mac_tcr & MGBE_MAC_TCR_TSADDREG) == 0U) { - return 0; - } - - retry++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return -1; -} - -/** - * @brief mgbe_config_addend - Configure addend - * - * Algorithm: Updates the Addend value in HW register - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] addend: Addend value to be configured - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_config_addend(struct osi_core_priv_data *osi_core, - unsigned int addend) -{ - unsigned int mac_tcr; - void *addr = osi_core->base; - int ret; - - /* To be sure previous write was flushed (if Any) */ - ret = mgbe_poll_for_addend_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - /* write addend value to MAC_Timestamp_Addend register */ - osi_writela(osi_core, addend, (unsigned char *)addr + MGBE_MAC_TAR); - - /* issue command to update the configured addend value */ - mac_tcr |= MGBE_MAC_TCR_TSADDREG; - osi_writela(osi_core, mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); - - ret = mgbe_poll_for_addend_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** - * @brief mgbe_poll_for_update_ts_complete - Poll for update time stamp - * - * Algorithm: Read time stamp update value from TCR register until it is - * equal to zero. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] mac_tcr: Address to store time stamp control register read value - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int mgbe_poll_for_update_ts_complete( - struct osi_core_priv_data *osi_core, - unsigned int *mac_tcr) -{ - unsigned int retry = 0U; - - while (retry < OSI_POLL_COUNT) { - /* Read and Check TSUPDT in MAC_Timestamp_Control register */ - *mac_tcr = osi_readla(osi_core, (unsigned char *) - osi_core->base + MGBE_MAC_TCR); - if ((*mac_tcr & MGBE_MAC_TCR_TSUPDT) == 0U) { - return 0; - } - - retry++; - osi_core->osd_ops.udelay(OSI_DELAY_1000US); - } - - return -1; -} - -/** - * @brief mgbe_adjust_mactime - Adjust MAC time with system time - * - * Algorithm: Update MAC time with system time - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] sec: Seconds to be configured - * @param[in] nsec: Nano seconds to be configured - * @param[in] add_sub: To decide on add/sub with system time - * @param[in] one_nsec_accuracy: One nano second accuracy - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->ptp_config.one_nsec_accuracy need to be set to 1 - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int mgbe_adjust_mactime(struct osi_core_priv_data *osi_core, - unsigned int sec, unsigned int nsec, - unsigned int add_sub, - unsigned int one_nsec_accuracy) -{ - void *addr = osi_core->base; - unsigned int mac_tcr; - unsigned int value = 0; - unsigned long long temp = 0; - int ret; - - /* To be sure previous write was flushed (if Any) */ - ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - if (add_sub != 0U) { - /* If the new sec value needs to be subtracted with - * the system time, then MAC_STSUR reg should be - * programmed with (2^32 – ) - */ - temp = (TWO_POWER_32 - sec); - if (temp < UINT_MAX) { - sec = (unsigned int)temp; - } else { - /* do nothing here */ - } - - /* If the new nsec value need to be subtracted with - * the system time, then MAC_STNSUR.TSSS field should be - * programmed with, (10^9 - ) if - * MAC_TCR.TSCTRLSSR is set or - * (2^32 - if MAC_TCR.TSCTRLSSR is reset) - */ - if (one_nsec_accuracy == OSI_ENABLE) { - if (nsec < UINT_MAX) { - nsec = (TEN_POWER_9 - nsec); - } - } else { - if (nsec < UINT_MAX) { - nsec = (TWO_POWER_31 - nsec); - } - } - } - - /* write seconds value to MAC_System_Time_Seconds_Update register */ - osi_writela(osi_core, sec, (unsigned char *)addr + MGBE_MAC_STSUR); - - /* write nano seconds value and add_sub to - * MAC_System_Time_Nanoseconds_Update register - */ - value |= nsec; - value |= (add_sub << MGBE_MAC_STNSUR_ADDSUB_SHIFT); - osi_writela(osi_core, value, (unsigned char *)addr + MGBE_MAC_STNSUR); - - /* issue command to initialize system time with the value - * specified in MAC_STSUR and MAC_STNSUR - */ - mac_tcr |= MGBE_MAC_TCR_TSUPDT; - osi_writela(osi_core, mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); - - ret = mgbe_poll_for_update_ts_complete(osi_core, &mac_tcr); - if (ret == -1) { - return -1; - } - - return 0; -} - -/** - * @brief mgbe_config_tscr - Configure Time Stamp Register - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] ptp_filter: PTP rx filter parameters - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_config_tscr(struct osi_core_priv_data *osi_core, - unsigned int ptp_filter) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int mac_tcr = 0; - nveu32_t value = 0x0U; - void *addr = osi_core->base; - - if (ptp_filter != OSI_DISABLE) { - mac_tcr = (OSI_MAC_TCR_TSENA | - OSI_MAC_TCR_TSCFUPDT | - OSI_MAC_TCR_TSCTRLSSR); - - if ((ptp_filter & OSI_MAC_TCR_SNAPTYPSEL_1) == - OSI_MAC_TCR_SNAPTYPSEL_1) { - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_1; - } - if ((ptp_filter & OSI_MAC_TCR_SNAPTYPSEL_2) == - OSI_MAC_TCR_SNAPTYPSEL_2) { - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_2; - } - if ((ptp_filter & OSI_MAC_TCR_SNAPTYPSEL_3) == - OSI_MAC_TCR_SNAPTYPSEL_3) { - mac_tcr |= OSI_MAC_TCR_SNAPTYPSEL_3; - } - if ((ptp_filter & OSI_MAC_TCR_TSIPV4ENA) == - OSI_MAC_TCR_TSIPV4ENA) { - mac_tcr |= OSI_MAC_TCR_TSIPV4ENA; - } - if ((ptp_filter & OSI_MAC_TCR_TSIPV6ENA) == - OSI_MAC_TCR_TSIPV6ENA) { - mac_tcr |= OSI_MAC_TCR_TSIPV6ENA; - } - if ((ptp_filter & OSI_MAC_TCR_TSEVENTENA) == - OSI_MAC_TCR_TSEVENTENA) { - mac_tcr |= OSI_MAC_TCR_TSEVENTENA; - } - if ((ptp_filter & OSI_MAC_TCR_TSMASTERENA) == - OSI_MAC_TCR_TSMASTERENA) { - mac_tcr |= OSI_MAC_TCR_TSMASTERENA; - } - if ((ptp_filter & OSI_MAC_TCR_TSVER2ENA) == - OSI_MAC_TCR_TSVER2ENA) { - mac_tcr |= OSI_MAC_TCR_TSVER2ENA; - } - if ((ptp_filter & OSI_MAC_TCR_TSIPENA) == - OSI_MAC_TCR_TSIPENA) { - mac_tcr |= OSI_MAC_TCR_TSIPENA; - } - if ((ptp_filter & OSI_MAC_TCR_AV8021ASMEN) == - OSI_MAC_TCR_AV8021ASMEN) { - mac_tcr |= OSI_MAC_TCR_AV8021ASMEN; - } - if ((ptp_filter & OSI_MAC_TCR_TSENALL) == - OSI_MAC_TCR_TSENALL) { - mac_tcr |= OSI_MAC_TCR_TSENALL; - } - if ((ptp_filter & OSI_MAC_TCR_CSC) == - OSI_MAC_TCR_CSC) { - mac_tcr |= OSI_MAC_TCR_CSC; - } - } else { - /* Disabling the MAC time stamping */ - mac_tcr = OSI_DISABLE; - } - - osi_writela(osi_core, mac_tcr, (unsigned char *)addr + MGBE_MAC_TCR); - - value = osi_readla(osi_core, (nveu8_t *)addr + MGBE_MAC_PPS_CTL); - value &= ~MGBE_MAC_PPS_CTL_PPSCTRL0; - if (l_core->pps_freq == OSI_ENABLE) { - value |= OSI_ENABLE; - } - osi_writela(osi_core, value, (nveu8_t *)addr + MGBE_MAC_PPS_CTL); -} - -/** - * @brief mgbe_config_ssir - Configure SSIR - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] ptp_clock: PTP required clock frequency - * - * @note MAC should be init and started. see osi_start_mac() - */ -static void mgbe_config_ssir(struct osi_core_priv_data *const osi_core, - const unsigned int ptp_clock) -{ - unsigned long long val; - unsigned int mac_tcr; - void *addr = osi_core->base; - - mac_tcr = osi_readla(osi_core, (unsigned char *)addr + MGBE_MAC_TCR); - - /* convert the PTP required clock frequency to nano second. - * formula is : ((1/ptp_clock) * 1000000000) - * where, ptp_clock = OSI_PTP_REQ_CLK_FREQ if FINE correction - * and ptp_clock = PTP reference clock if COARSE correction - */ - if ((mac_tcr & MGBE_MAC_TCR_TSCFUPDT) == MGBE_MAC_TCR_TSCFUPDT) { - if (osi_core->pre_si == OSI_ENABLE) { - val = OSI_PTP_SSINC_16; - } else { - /* For silicon */ - val = OSI_PTP_SSINC_4; - } - } else { - val = ((1U * OSI_NSEC_PER_SEC) / ptp_clock); - } - - /* 0.465ns accurecy */ - if ((mac_tcr & MGBE_MAC_TCR_TSCTRLSSR) == 0U) { - if (val < UINT_MAX) { - val = (val * 1000U) / 465U; - } - } - - val |= (val << MGBE_MAC_SSIR_SSINC_SHIFT); - - /* update Sub-second Increment Value */ - if (val < UINT_MAX) { - osi_writela(osi_core, (unsigned int)val, - (unsigned char *)addr + MGBE_MAC_SSIR); - } -} - -/** - * @brief mgbe_set_mode - Setting the mode. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] mode: mode to be set. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nve32_t mgbe_set_mode(OSI_UNUSED - struct osi_core_priv_data *const osi_core, - OSI_UNUSED const nve32_t mode) -{ - return 0; -} - -/** - * @brief mgbe_read_reg - Read a register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t mgbe_read_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) -{ - return osi_readla(osi_core, (nveu8_t *)osi_core->base + reg); -} - -/** - * @brief mgbe_write_reg - Write a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t mgbe_write_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, - const nve32_t reg) -{ - osi_writela(osi_core, val, (nveu8_t *)osi_core->base + reg); - return 0; -} - -#ifdef MACSEC_SUPPORT -/** - * @brief mgbe_read_macsec_reg - Read a MACSEC register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t mgbe_read_macsec_reg(struct osi_core_priv_data *const osi_core, - const nve32_t reg) -{ - return osi_readla(osi_core, (nveu8_t *)osi_core->macsec_base + reg); -} - -/** - * @brief mgbe_write_macsec_reg - Write to a MACSEC reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nveu32_t mgbe_write_macsec_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t val, const nve32_t reg) -{ - osi_writela(osi_core, val, (nveu8_t *)osi_core->macsec_base + reg); - return 0; -} -#endif /* MACSEC_SUPPORT */ - -/** - * @brief mgbe_validate_core_regs - Validates MGBE core registers. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nve32_t mgbe_validate_core_regs( - OSI_UNUSED - struct osi_core_priv_data *const osi_core) -{ - return 0; -} - -/** - * @brief eqos_write_reg - Write a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nve32_t mgbe_config_tx_status(OSI_UNUSED - struct osi_core_priv_data *const osi_core, - OSI_UNUSED const nveu32_t tx_status) -{ - return 0; -} - -/** - * @brief eqos_write_reg - Write a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static nve32_t mgbe_config_rx_crc_check(OSI_UNUSED - struct osi_core_priv_data *const osi_core, - OSI_UNUSED const nveu32_t crc_chk) -{ - return 0; -} - -/** - * @brief eqos_write_reg - Write a reg - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] val: Value to be written. - * @param[in] reg: Register address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * @retval 0 - */ -static void mgbe_set_mdc_clk_rate(OSI_UNUSED - struct osi_core_priv_data *const osi_core, - OSI_UNUSED - const nveu64_t csr_clk_rate) -{ -} - -#ifdef MACSEC_SUPPORT -/** - * @brief mgbe_config_for_macsec - Configure MAC according to macsec IAS - * - * @note - * Algorithm: - * - Stop MAC Tx - * - Update MAC IPG value to accommodate macsec 32 byte SECTAG. - * - Start MAC Tx - * - Update MTL_EST value as MACSEC is enabled/disabled - * - * @param[in] osi_core: OSI core private data. - * @param[in] enable: Enable or Disable MAC Tx engine - * - * @pre - * 1) MAC has to be out of reset. - * 2) Shall not use this ipg value in half duplex mode - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void mgbe_config_for_macsec(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - nveu32_t value = 0U, temp = 0U; - - if ((enable != OSI_ENABLE) && (enable != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Failed to config MGBE per MACSEC\n", 0ULL); - return; - } - /* stop MAC Tx */ - mgbe_config_mac_tx(osi_core, OSI_DISABLE); - if (enable == OSI_ENABLE) { - /* Configure IPG {EIPG,IPG} value according to macsec IAS in - * MAC_Tx_Configuration and MAC_Extended_Configuration - * IPG (12 B[default] + 32 B[sectag]) = 352 bits - */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_TMCR); - value &= ~MGBE_MAC_TMCR_IPG_MASK; - value |= MGBE_MAC_TMCR_IFP; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_TMCR); - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - value |= MGBE_MAC_EXT_CNF_EIPG; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - } else { - /* Update MAC IPG to default value 12B */ - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_TMCR); - value &= ~MGBE_MAC_TMCR_IPG_MASK; - value &= ~MGBE_MAC_TMCR_IFP; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_TMCR); - value = osi_readla(osi_core, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - value &= ~MGBE_MAC_EXT_CNF_EIPG_MASK; - osi_writela(osi_core, value, (nveu8_t *)osi_core->base + - MGBE_MAC_EXT_CNF); - } - /* start MAC Tx */ - mgbe_config_mac_tx(osi_core, OSI_ENABLE); - - if (osi_core->hw_feature != OSI_NULL) { - /* Program MTL_EST depending on MACSEC enable/disable */ - if (osi_core->hw_feature->est_sel == OSI_ENABLE) { - value = osi_readla(osi_core, - (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - value &= ~MGBE_MTL_EST_CONTROL_CTOV; - if (enable == OSI_ENABLE) { - temp = MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND; - temp = temp << MGBE_MTL_EST_CONTROL_CTOV_SHIFT; - value |= temp & MGBE_MTL_EST_CONTROL_CTOV; - } else { - temp = MGBE_MTL_EST_CTOV_RECOMMEND; - temp = temp << MGBE_MTL_EST_CONTROL_CTOV_SHIFT; - value |= temp & MGBE_MTL_EST_CONTROL_CTOV; - } - osi_writela(osi_core, value, - (nveu8_t *)osi_core->base + - MGBE_MTL_EST_CONTROL); - } else { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_HW_FAIL, "Error: osi_core->hw_feature is NULL\n", - 0ULL); - } - } -} -#endif /* MACSEC_SUPPORT */ - -/** - * @brief mgbe_init_core_ops - Initialize MGBE MAC core operations - */ -void mgbe_init_core_ops(struct core_ops *ops) -{ - ops->poll_for_swr = mgbe_poll_for_swr; - ops->core_init = mgbe_core_init; - ops->core_deinit = mgbe_core_deinit; - ops->validate_regs = mgbe_validate_core_regs; - ops->start_mac = mgbe_start_mac; - ops->stop_mac = mgbe_stop_mac; - ops->handle_common_intr = mgbe_handle_common_intr; - /* only MGBE supports full duplex */ - ops->set_mode = mgbe_set_mode; - /* by default speed is 10G */ - ops->set_speed = mgbe_set_speed; - ops->pad_calibrate = mgbe_pad_calibrate; - ops->set_mdc_clk_rate = mgbe_set_mdc_clk_rate; - ops->flush_mtl_tx_queue = mgbe_flush_mtl_tx_queue; - ops->config_mac_loopback = mgbe_config_mac_loopback; - ops->set_avb_algorithm = mgbe_set_avb_algorithm; - ops->get_avb_algorithm = mgbe_get_avb_algorithm, - ops->config_fw_err_pkts = mgbe_config_fw_err_pkts; - ops->config_tx_status = mgbe_config_tx_status; - ops->config_rx_crc_check = mgbe_config_rx_crc_check; - ops->config_flow_control = mgbe_config_flow_control; - ops->config_arp_offload = mgbe_config_arp_offload; - ops->config_ptp_offload = mgbe_config_ptp_offload; - ops->config_rxcsum_offload = mgbe_config_rxcsum_offload; - ops->config_mac_pkt_filter_reg = mgbe_config_mac_pkt_filter_reg; - ops->update_mac_addr_low_high_reg = mgbe_update_mac_addr_low_high_reg; - ops->config_l3_l4_filter_enable = mgbe_config_l3_l4_filter_enable; - ops->config_l3_filters = mgbe_config_l3_filters; - ops->update_ip4_addr = mgbe_update_ip4_addr; - ops->update_ip6_addr = mgbe_update_ip6_addr; - ops->config_l4_filters = mgbe_config_l4_filters; - ops->update_l4_port_no = mgbe_update_l4_port_no; - ops->config_vlan_filtering = mgbe_config_vlan_filtering; - ops->set_systime_to_mac = mgbe_set_systime_to_mac; - ops->config_addend = mgbe_config_addend; - ops->adjust_mactime = mgbe_adjust_mactime; - ops->config_tscr = mgbe_config_tscr; - ops->config_ssir = mgbe_config_ssir, - ops->config_ptp_rxq = mgbe_config_ptp_rxq; - ops->write_phy_reg = mgbe_write_phy_reg; - ops->read_phy_reg = mgbe_read_phy_reg; - ops->save_registers = mgbe_save_registers; - ops->restore_registers = mgbe_restore_registers; - ops->read_mmc = mgbe_read_mmc; - ops->reset_mmc = mgbe_reset_mmc; - ops->configure_eee = mgbe_configure_eee; - ops->get_hw_features = mgbe_get_hw_features; - ops->config_rss = mgbe_config_rss; - ops->hw_config_est = mgbe_hw_config_est; - ops->hw_config_fpe = mgbe_hw_config_fpe; - ops->config_frp = mgbe_config_frp; - ops->update_frp_entry = mgbe_update_frp_entry; - ops->update_frp_nve = mgbe_update_frp_nve; - ops->ptp_tsc_capture = mgbe_ptp_tsc_capture; - ops->write_reg = mgbe_write_reg; - ops->read_reg = mgbe_read_reg; -#ifdef MACSEC_SUPPORT - ops->write_macsec_reg = mgbe_write_macsec_reg; - ops->read_macsec_reg = mgbe_read_macsec_reg; - ops->macsec_config_mac = mgbe_config_for_macsec; -#endif /* MACSEC_SUPPORT */ -#ifdef HSI_SUPPORT - ops->core_hsi_configure = mgbe_hsi_configure; -#endif -}; diff --git a/osi/core/mgbe_core.h b/osi/core/mgbe_core.h deleted file mode 100644 index 8fc3368..0000000 --- a/osi/core/mgbe_core.h +++ /dev/null @@ -1,1146 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 MGBE_CORE_H_ -#define MGBE_CORE_H_ - -/** - * @addtogroup - MGBE-LPI LPI configuration macros - * - * @brief LPI timers and config register field masks. - * @{ - */ -/* LPI LS timer - minimum time (in milliseconds) for which the link status from - * PHY should be up before the LPI pattern can be transmitted to the PHY. - * Default 1sec. - */ -#define MGBE_DEFAULT_LPI_LS_TIMER (unsigned int)1000 -#define MGBE_LPI_LS_TIMER_MASK 0x3FFU -#define MGBE_LPI_LS_TIMER_SHIFT 16U -/* LPI TW timer - minimum time (in microseconds) for which MAC wait after it - * stops transmitting LPI pattern before resuming normal tx. - * Default 21us - */ -#define MGBE_DEFAULT_LPI_TW_TIMER 0x15U -#define MGBE_LPI_TW_TIMER_MASK 0xFFFFU -/* LPI entry timer - Time in microseconds that MAC will wait to enter LPI mode - * after all tx is complete. - * Default 1sec. - */ -#define MGBE_LPI_ENTRY_TIMER_MASK 0xFFFF8U -/* 1US TIC counter - This counter should be programmed with the number of clock - * cycles of CSR clock that constitutes a period of 1us. - * it should be APB clock in MHZ i.e 480-1 for silicon and 13MHZ-1 for uFPGA - */ -#define MGBE_1US_TIC_COUNTER 0x1DF - -/** @} */ - -/** - * @addtogroup MGBE-MAC MAC register offsets - * - * @brief MGBE MAC register offsets - * @{ - */ -#define MGBE_MAC_TMCR 0x0000 -#define MGBE_MAC_RMCR 0x0004 -#define MGBE_MAC_PFR 0x0008 -#define MGBE_MAC_HTR_REG(x) ((0x0004U * (x)) + 0x0010U) -#define MGBE_MAC_VLAN_TR 0x0050 -#define MGBE_MAC_VLANTIR 0x0060 -#define MGBE_MAC_QX_TX_FLW_CTRL(x) ((0x0004U * (x)) + 0x0070U) -#define MGBE_MAC_RX_FLW_CTRL 0x0090 -#define MGBE_MAC_RQC4R 0x0094 -#define MGBE_MAC_RQC0R 0x00A0 -#define MGBE_MAC_RQC1R 0x00A4 -#define MGBE_MAC_RQC2R 0x00A8 -#define MGBE_MAC_ISR 0x00B0 -#define MGBE_MAC_IER 0x00B4 -#define MGBE_MAC_RX_TX_STS 0x00B8 -#define MGBE_MAC_PMTCSR 0x00C0 -#define MGBE_MAC_LPI_CSR 0x00D0 -#define MGBE_MAC_LPI_TIMER_CTRL 0x00D4 -#define MGBE_MAC_LPI_EN_TIMER 0x00D8 -#define MGBE_MAC_1US_TIC_COUNT 0x00DC -#define MGBE_MAC_EXT_CNF 0x0140 -#define MGBE_MDIO_SCCD 0x0204 -#define MGBE_MDIO_SCCA 0x0200 -#define MGBE_MAC_FPE_CTS 0x0280 -#define MGBE_MAC_CSR_SW_CTL 0x0290 -#define MGBE_MAC_MA0HR 0x0300 -#define MGBE_MAC_ADDRH(x) ((0x0008U * (x)) + 0x0300U) -#define MGBE_MAC_MA0LR 0x0304 -#define MGBE_MAC_ADDRL(x) ((0x0008U * (x)) + 0x0304U) -#define MGBE_MAC_INDIR_AC 0x0700 -#define MGBE_MAC_INDIR_DATA 0x0704 -#define MGBE_MMC_TX_INTR_EN 0x0810 -#define MGBE_MMC_RX_INTR_EN 0x080C -#define MGBE_MMC_CNTRL 0x0800 -#define MGBE_MAC_L3L4_ADDR_CTR 0x0C00 -#define MGBE_MAC_L3L4_DATA 0x0C04 -#define MGBE_MAC_ARPPA 0x0C10 -#define MGBE_MAC_RSS_CTRL 0x0C80 -#define MGBE_MAC_RSS_ADDR 0x0C88 -#define MGBE_MAC_RSS_DATA 0x0C8C -#define MGBE_MAC_TCR 0x0D00 -#define MGBE_MAC_SSIR 0x0D04 -#define MGBE_MAC_STSR 0x0D08 -#define MGBE_MAC_STNSR 0x0D0C -#define MGBE_MAC_STSUR 0x0D10 -#define MGBE_MAC_STNSUR 0x0D14 -#define MGBE_MAC_TAR 0x0D18 -#define MGBE_MAC_TSS 0x0D20 -#define MGBE_MAC_TSNSSEC 0x0D30 -#define MGBE_MAC_TSSEC 0x0D34 -#define MGBE_MAC_TSPKID 0x0D38 -#define MGBE_MAC_PPS_CTL 0x0D70 -#define MGBE_MAC_PTO_CR 0x0DC0 -#define MGBE_MAC_PIDR0 0x0DC4 -#define MGBE_MAC_PIDR1 0x0DC8 -#define MGBE_MAC_PIDR2 0x0DCC -/** @} */ - -/** - * @addtogroup MGBE-WRAPPER MGBE Wrapper register offsets - * - * @brief MGBE Wrapper register offsets - * @{ - */ -#define MGBE_WRAP_AXI_ASID0_CTRL 0x8400 -#define MGBE_WRAP_AXI_ASID1_CTRL 0x8404 -#define MGBE_WRAP_AXI_ASID2_CTRL 0x8408 -#define MGBE_WRAP_COMMON_INTR_ENABLE 0x8704 -#define MGBE_REGISTER_PARITY_ERR OSI_BIT(5) -#define MGBE_CORE_CORRECTABLE_ERR OSI_BIT(4) -#define MGBE_CORE_UNCORRECTABLE_ERR OSI_BIT(3) -#define MGBE_MAC_SBD_INTR OSI_BIT(2) -#define MGBE_WRAP_COMMON_INTR_STATUS 0x8708 -#define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) -#define MGBE_VIRTUAL_APB_ERR_CTRL 0x8300 -#define MGBE_WRAP_SYNC_TSC_PTP_CAPTURE 0x800CU -#define MGBE_WRAP_TSC_CAPTURE_LOW 0x8010U -#define MGBE_WRAP_TSC_CAPTURE_HIGH 0x8014U -#define MGBE_WRAP_PTP_CAPTURE_LOW 0x8018U -#define MGBE_WRAP_PTP_CAPTURE_HIGH 0x801CU -/** @} */ - -/** - * @addtogroup MGBE MAC hash table defines - * - * @brief MGBE MAC hash table Control register - * filed type defines. - * @{ - */ -#define MGBE_MAX_HTR_REGS 4U -/** @} */ - -/** - * @addtogroup MGBE MAC Mode Select Group - * - * @brief MGBE MAC Indirect Access control and status for - * Mode Select type defines. - * @{ - */ -#define MGBE_MAC_XDCS_DMA_MAX 0x3FFU -#define MGBE_MAC_INDIR_AC_OB_WAIT 10U -#define MGBE_MAC_INDIR_AC_OB_RETRY 10U - -#define MGBE_MAC_DCHSEL 0U -#define MGBE_MAC_PCCTRL 1U -#define MGBE_MAC_PCNTRL 2U -#define MGBE_MAC_DPCSEL 3U -#define MGBE_MAC_VPCSEL 4U -#define MGBE_MAC_LPCSEL 5U -#define MGBE_MAC_APCSEL 6U -#define MGBE_MAC_PC_STATUS 7U - -/* MGBE_MAC_INDIR_AC register defines */ -#define MGBE_MAC_INDIR_AC_MSEL (OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define MGBE_MAC_INDIR_AC_MSEL_SHIFT 16U -#define MGBE_MAC_INDIR_AC_AOFF (OSI_BIT(15) | OSI_BIT(14) | \ - OSI_BIT(13) | OSI_BIT(12) | \ - OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define MGBE_MAC_INDIR_AC_AOFF_SHIFT 8U -#define MGBE_MAC_INDIR_AC_AUTO OSI_BIT(5) -#define MGBE_MAC_INDIR_AC_CMD OSI_BIT(1) -#define MGBE_MAC_INDIR_AC_OB OSI_BIT(0) -/** @} */ - -/** - * @addtogroup MGBE MAC L3L4 defines - * - * @brief MGBE L3L4 Address Control register - * IDDR filter filed type defines - * @{ - */ -#define MGBE_MAX_VLAN_FILTER 32U -#define MGBE_MAC_XB_WAIT 10U -#define MGBE_MAC_L3L4_CTR 0x0 -#define MGBE_MAC_L4_ADDR 0x1 -#define MGBE_MAC_L3_AD0R 0x4 -#define MGBE_MAC_L3_AD1R 0x5 -#define MGBE_MAC_L3_AD2R 0x6 -#define MGBE_MAC_L3_AD3R 0x7 - -#define MGBE_MAC_L3L4_CTR_DMCHEN0 OSI_BIT(31) -#define MGBE_MAC_L3L4_CTR_DMCHEN0_SHIFT 31 -#define MGBE_MAC_L3L4_CTR_DMCHN0 (OSI_BIT(24) | OSI_BIT(25) | \ - OSI_BIT(26) | OSI_BIT(27)) -#define MGBE_MAC_L3L4_CTR_DMCHN0_SHIFT 24 -#define MGBE_MAC_L3L4_CTR_L4DPIM0 OSI_BIT(21) -#define MGBE_MAC_L3L4_CTR_L4DPIM0_SHIFT 21 -#define MGBE_MAC_L3L4_CTR_L4DPM0 OSI_BIT(20) -#define MGBE_MAC_L3L4_CTR_L4SPIM0 OSI_BIT(19) -#define MGBE_MAC_L3L4_CTR_L4SPIM0_SHIFT 19 -#define MGBE_MAC_L3L4_CTR_L4SPM0 OSI_BIT(18) -#define MGBE_MAC_L3L4_CTR_L4PEN0 OSI_BIT(16) -#define MGBE_MAC_L3L4_CTR_L3HDBM0 (OSI_BIT(11) | OSI_BIT(12) | \ - OSI_BIT(13) | OSI_BIT(14) | \ - OSI_BIT(15)) -#define MGBE_MAC_L3L4_CTR_L3HSBM0 (OSI_BIT(6) | OSI_BIT(7) | \ - OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10)) -#define MGBE_MAC_L3L4_CTR_L3DAIM0 OSI_BIT(5) -#define MGBE_MAC_L3L4_CTR_L3DAIM0_SHIFT 5 -#define MGBE_MAC_L3L4_CTR_L3DAM0 OSI_BIT(4) -#define MGBE_MAC_L3L4_CTR_L3SAIM0 OSI_BIT(3) -#define MGBE_MAC_L3L4_CTR_L3SAIM0_SHIFT 3 -#define MGBE_MAC_L3L4_CTR_L3SAM0 OSI_BIT(2) -#define MGBE_MAC_L3L4_CTR_L3PEN0 OSI_BIT(0) -#define MGBE_MAC_L3_IP6_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3SAM0 | \ - MGBE_MAC_L3L4_CTR_L3SAIM0 | \ - MGBE_MAC_L3L4_CTR_L3DAM0 | \ - MGBE_MAC_L3L4_CTR_L3DAIM0 | \ - MGBE_MAC_L3L4_CTR_DMCHEN0 | \ - MGBE_MAC_L3L4_CTR_DMCHN0) -#define MGBE_MAC_L3_IP4_SA_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3SAM0 | \ - MGBE_MAC_L3L4_CTR_L3SAIM0 | \ - MGBE_MAC_L3L4_CTR_DMCHEN0 | \ - MGBE_MAC_L3L4_CTR_DMCHN0) -#define MGBE_MAC_L3_IP4_DA_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L3DAM0 | \ - MGBE_MAC_L3L4_CTR_L3DAIM0 | \ - MGBE_MAC_L3L4_CTR_DMCHEN0 | \ - MGBE_MAC_L3L4_CTR_DMCHN0) -#define MGBE_MAC_L4_SP_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L4SPM0 | \ - MGBE_MAC_L3L4_CTR_L4SPIM0 | \ - MGBE_MAC_L3L4_CTR_DMCHEN0 | \ - MGBE_MAC_L3L4_CTR_DMCHN0) -#define MGBE_MAC_L4_DP_CTRL_CLEAR (MGBE_MAC_L3L4_CTR_L4DPM0 | \ - MGBE_MAC_L3L4_CTR_L4DPIM0 | \ - MGBE_MAC_L3L4_CTR_DMCHEN0 | \ - MGBE_MAC_L3L4_CTR_DMCHN0) -#define MGBE_MAC_L3L4_CTRL_ALL (MGBE_MAC_L3_IP6_CTRL_CLEAR | \ - MGBE_MAC_L3_IP4_SA_CTRL_CLEAR | \ - MGBE_MAC_L3_IP4_DA_CTRL_CLEAR | \ - MGBE_MAC_L4_SP_CTRL_CLEAR | \ - MGBE_MAC_L4_DP_CTRL_CLEAR) -#define MGBE_MAC_L4_ADDR_SP_MASK 0x0000FFFFU -#define MGBE_MAC_L4_ADDR_DP_MASK 0xFFFF0000U -#define MGBE_MAC_L4_ADDR_DP_SHIFT 16 -#define MGBE_MAC_PPS_CTL_PPSCTRL0 (OSI_BIT(3) | OSI_BIT(2) |\ - OSI_BIT(1) | OSI_BIT(0)) -/** @} */ - -/** - * @addtogroup MGBE-DMA DMA register offsets - * - * @brief MGBE DMA register offsets - * @{ - */ -#define MGBE_DMA_MODE 0x3000 -#define MGBE_DMA_SBUS 0x3004 -#define MGBE_DMA_ISR 0x3008 -#define MGBE_DMA_TX_EDMA_CTRL 0x3040 -#define MGBE_DMA_RX_EDMA_CTRL 0x3044 -#define MGBE_DMA_CHX_STATUS(x) ((0x0080U * (x)) + 0x3160U) -#define MGBE_DMA_CHX_IER(x) ((0x0080U * (x)) + 0x3138U) -/** @} */ - -/** - * @addtogroup MGBE-MTL MTL register offsets - * - * @brief MGBE MTL register offsets - * @{ - */ -#define MGBE_MTL_OP_MODE 0x1000 -#define MGBE_MTL_INTR_STATUS 0x1020 -#define MGBE_MTL_RXQ_DMA_MAP0 0x1030 -#define MGBE_MTL_RXQ_DMA_MAP1 0x1034 -#define MGBE_MTL_RXQ_DMA_MAP2 0x1038 -#define MGBE_MTL_RXQ_DMA_MAP3 0x103b -#define MGBE_MTL_EST_CONTROL 0x1050 -#define MGBE_MTL_EST_OVERHEAD 0x1054 -#define MGBE_MTL_EST_STATUS 0x1058 -#define MGBE_MTL_EST_SCH_ERR 0x1060 -#define MGBE_MTL_EST_FRMS_ERR 0x1064 -#define MGBE_MTL_EST_FRMC_ERR 0x1068 -#define MGBE_MTL_EST_ITRE 0x1070 -#define MGBE_MTL_EST_GCL_CONTROL 0x1080 -#define MGBE_MTL_EST_DATA 0x1084 -#define MGBE_MTL_FPE_CTS 0x1090 -#define MGBE_MTL_FPE_ADV 0x1094 -#define MGBE_MTL_CHX_TX_OP_MODE(x) ((0x0080U * (x)) + 0x1100U) -#define MGBE_MTL_TCQ_ETS_CR(x) ((0x0080U * (x)) + 0x1110U) -#define MGBE_MTL_TCQ_QW(x) ((0x0080U * (x)) + 0x1118U) -#define MGBE_MTL_TCQ_ETS_SSCR(x) ((0x0080U * (x)) + 0x111CU) -#define MGBE_MTL_TCQ_ETS_HCR(x) ((0x0080U * (x)) + 0x1120U) -#define MGBE_MTL_TCQ_ETS_LCR(x) ((0x0080U * (x)) + 0x1124U) -#define MGBE_MTL_CHX_RX_OP_MODE(x) ((0x0080U * (x)) + 0x1140U) -#define MGBE_MTL_RXQ_FLOW_CTRL(x) ((0x0080U * (x)) + 0x1150U) -#define MGBE_MTL_QINT_ENABLE(x) ((0x0080U * (x)) + 0x1170U) -#define MGBE_MTL_QINT_STATUS(x) ((0x0080U * (x)) + 0x1174U) -#define MGBE_MTL_TC_PRTY_MAP0 0x1040 -#define MGBE_MTL_TC_PRTY_MAP1 0x1044 -#define MGBE_MTL_RXP_CS 0x10A0 -#define MGBE_MTL_RXP_INTR_CS 0x10A4 -#define MGBE_MTL_RXP_IND_CS 0x10B0 -#define MGBE_MTL_RXP_IND_DATA 0x10B4 -/** @} */ - -/** - * @addtogroup MGBE-MTL FRP Indirect Access register defines - * - * @brief MGBE MTL register offsets - * @{ - */ -#define MGBE_MTL_FRP_READ_UDELAY 1U -#define MGBE_MTL_FRP_READ_RETRY 1000U - -#define MGBE_MTL_OP_MODE_FRPE OSI_BIT(15) -/* FRP Control and Status register defines */ -#define MGBE_MTL_RXP_CS_RXPI OSI_BIT(31) -#define MGBE_MTL_RXP_CS_PIPE (OSI_BIT(30) | OSI_BIT(29) | \ - OSI_BIT(28)) -#define MGBE_MTL_RXP_CS_NPE (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define MGBE_MTL_RXP_CS_NPE_SHIFT 16U -#define MGBE_MTL_RXP_CS_FPE_RCH (OSI_BIT(15) | OSI_BIT(14) | \ - OSI_BIT(13) | OSI_BIT(12)) -#define MGBE_MTL_RXP_CS_NVE (OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4) | \ - OSI_BIT(3) | OSI_BIT(2) | \ - OSI_BIT(1) | OSI_BIT(0)) -/* FRP Interrupt Control and Status register */ -#define MGBE_MTL_RXP_INTR_CS_PDRFIE OSI_BIT(19) -#define MGBE_MTL_RXP_INTR_CS_FOOVIE OSI_BIT(18) -#define MGBE_MTL_RXP_INTR_CS_NPEOVIE OSI_BIT(17) -#define MGBE_MTL_RXP_INTR_CS_NVEOVIE OSI_BIT(16) -#define MGBE_MTL_RXP_INTR_CS_PDRFIS OSI_BIT(3) -#define MGBE_MTL_RXP_INTR_CS_FOOVIS OSI_BIT(2) -#define MGBE_MTL_RXP_INTR_CS_NPEOVIS OSI_BIT(1) -#define MGBE_MTL_RXP_INTR_CS_NVEOVIS OSI_BIT(0) -/* Indirect Instruction Table defines */ -#define MGBE_MTL_FRP_IE0(x) ((x) * 0x4U + 0x0U) -#define MGBE_MTL_FRP_IE1(x) ((x) * 0x4U + 0x1U) -#define MGBE_MTL_FRP_IE2(x) ((x) * 0x4U + 0x2U) -#define MGBE_MTL_FRP_IE3(x) ((x) * 0x4U + 0x3U) -#define MGBE_MTL_FRP_IE2_DCH (OSI_BIT(31) | OSI_BIT(30) | \ - OSI_BIT(29) | OSI_BIT(28) | \ - OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define MGBE_MTL_FRP_IE2_DCH_SHIFT 24U -#define MGBE_MTL_FRP_IE2_DCH_MASK 0xFFU -#define MGBE_MTL_FRP_IE2_OKI (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define MGBE_MTL_FRP_IE2_OKI_SHIFT 16U -#define MGBE_MTL_FRP_IE2_FO (OSI_BIT(13) | OSI_BIT(12) | \ - OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define MGBE_MTL_FRP_IE2_FO_SHIFT 8U -#define MGBE_MTL_FRP_IE2_NC OSI_BIT(3) -#define MGBE_MTL_FRP_IE2_IM OSI_BIT(2) -#define MGBE_MTL_FRP_IE2_RF OSI_BIT(1) -#define MGBE_MTL_FRP_IE2_AF OSI_BIT(0) -#define MGBE_MTL_FRP_IE3_DCH_MASK 0xFFFFU -/* Indirect register defines */ -#define MGBE_MTL_RXP_DROP_CNT 0U -#define MGBE_MTL_RXP_ERROR_CNT 1U -#define MGBE_MTL_RXP_BYPASS_CNT 2U -#define MGBE_MTL_RXP_ACCEPT_CNT(x) ((0x10 * (x)) + 0x40) -#define MGBE_MTL_RXP_IND_CS_BUSY OSI_BIT(31) -#define MGBE_MTL_RXP_IND_CS_ACCSEL OSI_BIT(24) -#define MGBE_MTL_RXP_IND_CS_RXPEIEC (OSI_BIT(22) | OSI_BIT(21)) -#define MGBE_MTL_RXP_IND_CS_RXPEIEE OSI_BIT(20) -#define MGBE_MTL_RXP_IND_CS_CRWEN OSI_BIT(18) -#define MGBE_MTL_RXP_IND_CS_CRWSEL OSI_BIT(17) -#define MGBE_MTL_RXP_IND_CS_WRRDN OSI_BIT(16) -#define MGBE_MTL_RXP_IND_CS_ADDR (OSI_BIT(9) | OSI_BIT(8) | \ - OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4) | \ - OSI_BIT(3) | OSI_BIT(2) | \ - OSI_BIT(1) | OSI_BIT(0)) -/** @} */ - -/** - * @addtogroup HW Register BIT values - * - * @brief consists of corresponding MGBE MAC, MTL register bit values - * @{ - */ -#define MGBE_DMA_MODE_SWR OSI_BIT(0) -#define MGBE_MTL_TCQ_ETS_CR_SLC_MASK (OSI_BIT(6) | OSI_BIT(5) | \ - OSI_BIT(4)) -#define MGBE_MTL_TCQ_ETS_CR_CC OSI_BIT(3) -#define MGBE_MTL_TCQ_ETS_CR_CC_SHIFT 3U -#define MGBE_MTL_TCQ_ETS_CR_AVALG (OSI_BIT(1) | OSI_BIT(0)) -#define MGBE_MTL_TCQ_ETS_CR_AVALG_SHIFT 0U -#define MGBE_MTL_TCQ_ETS_QW_ISCQW_MASK 0x001FFFFFU -#define MGBE_MTL_TCQ_ETS_SSCR_SSC_MASK 0x0000FFFFU -#define MGBE_MTL_TCQ_ETS_HCR_HC_MASK 0x1FFFFFFFU -#define MGBE_MTL_TCQ_ETS_LCR_LC_MASK 0x1FFFFFFFU -#define MGBE_MTL_TX_OP_MODE_Q2TCMAP (OSI_BIT(10) | OSI_BIT(9) |\ - OSI_BIT(8)) -#define MGBE_MTL_TX_OP_MODE_Q2TCMAP_SHIFT 8U -#define MGBE_MTL_TX_OP_MODE_TXQEN (OSI_BIT(3) | OSI_BIT(2)) -#define MGBE_MTL_TX_OP_MODE_TXQEN_SHIFT 2U -#define MGBE_MTL_CHX_TX_OP_MODE_Q2TC_SH 8U -#define MGBE_MTL_QTOMR_FTQ OSI_BIT(0) -#define MGBE_MTL_QTOMR_FTQ_LPOS OSI_BIT(0) -#define MGBE_MTL_TSF OSI_BIT(1) -#define MGBE_MTL_TXQEN OSI_BIT(3) -#define MGBE_MTL_RSF OSI_BIT(5) -#define MGBE_MTL_TCQ_QW_ISCQW OSI_BIT(4) -#define MGBE_MTL_QINT_TXUNIFS OSI_BIT(0) -#define MGBE_MTL_QINT_TXUIE OSI_BIT(0) -#define MGBE_MAC_RMCR_ACS OSI_BIT(1) -#define MGBE_MAC_RMCR_CST OSI_BIT(2) -#define MGBE_MAC_RMCR_IPC OSI_BIT(9) -#define MGBE_MAC_RXQC0_RXQEN_MASK 0x3U -#define MGBE_MAC_RXQC0_RXQEN_SHIFT(x) ((x) * 2U) -#define MGBE_MAC_RMCR_LM OSI_BIT(10) -#define MGBE_MAC_RMCR_ARPEN OSI_BIT(31) -#define MGBE_MDIO_SCCD_SBUSY OSI_BIT(22) -#define MGBE_MDIO_SCCA_DA_SHIFT 21U -#define MGBE_MDIO_SCCA_DA_MASK 0x1FU -#define MGBE_MDIO_C45_DA_SHIFT 16U -#define MGBE_MDIO_SCCA_PA_SHIFT 16U -#define MGBE_MDIO_SCCA_RA_MASK 0xFFFFU -#define MGBE_MDIO_SCCD_CMD_WR 1U -#define MGBE_MDIO_SCCD_CMD_RD 3U -#define MGBE_MDIO_SCCD_CMD_SHIFT 16U -#define MGBE_MDIO_SCCD_CR_SHIFT 19U -#define MGBE_MDIO_SCCD_CR_MASK 0x7U -#define MGBE_MDIO_SCCD_SDATA_MASK 0xFFFFU -#define MGBE_MDIO_SCCD_CRS OSI_BIT(31) -#define MGBE_MAC_RMCR_GPSLCE OSI_BIT(6) -#define MGBE_MAC_RMCR_WD OSI_BIT(7) -#define MGBE_MAC_RMCR_JE OSI_BIT(8) -#define MGBE_MAC_TMCR_IFP OSI_BIT(11) -#define MGBE_MAC_TMCR_DDIC OSI_BIT(1) -#define MGBE_MAC_TMCR_IPG_MASK 0x700U -#define MGBE_MAC_TMCR_JD OSI_BIT(16) -#define MGBE_MMC_CNTRL_CNTRST OSI_BIT(0) -#define MGBE_MMC_CNTRL_RSTONRD OSI_BIT(2) -#define MGBE_MMC_CNTRL_CNTMCT (OSI_BIT(4) | OSI_BIT(5)) -#define MGBE_MMC_CNTRL_CNTPRST OSI_BIT(7) -#define MGBE_MAC_RQC1R_PTPQ (OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define MGBE_MAC_RQC1R_PTPQ_SHIFT 24U -#define MGBE_MAC_RQC1R_TPQC1 OSI_BIT(22) -#define MGBE_MAC_RQC1R_TPQC0 OSI_BIT(21) -#define MGBE_MAC_RQC1R_OMCBCQ OSI_BIT(20) -#define MGBE_MAC_RQC1R_MCBCQEN OSI_BIT(15) -#define MGBE_MAC_RQC1R_MCBCQ (OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define MGBE_MAC_RQC1R_MCBCQ_SHIFT 8U -#define MGBE_MAC_RQC1R_MCBCQ_DEFAULT 9U -#define MGBE_MAC_RQC1R_RQ (OSI_BIT(7) | OSI_BIT(6) | \ - OSI_BIT(5) | OSI_BIT(4)) -#define MGBE_MAC_RQC1R_RQ_SHIFT 4U -#define MGBE_MAC_RQC4R_PMCBCQ (OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define MGBE_MAC_RQC4R_PMCBCQ_SHIFT 24U -#define MGBE_IMR_RGSMIIIE OSI_BIT(0) -#define MGBE_IMR_TSIE OSI_BIT(12) -#define MGBE_IMR_TXESIE OSI_BIT(13) -#define MGBE_IMR_FPEIE OSI_BIT(15) -#define MGBE_MAC_IMR_FPEIS OSI_BIT(16) -#define MGBE_ISR_TSIS OSI_BIT(12) -#define MGBE_DMA_ISR_MTLIS OSI_BIT(16) -#define MGBE_DMA_ISR_MACIS OSI_BIT(17) -#define MGBE_DMA_ISR_DCH0_DCH15_MASK 0x3FFU -#define MGBE_DMA_CHX_STATUS_TPS OSI_BIT(1) -#define MGBE_DMA_CHX_STATUS_TBU OSI_BIT(2) -#define MGBE_DMA_CHX_STATUS_RBU OSI_BIT(7) -#define MGBE_DMA_CHX_STATUS_RPS OSI_BIT(8) -#define MGBE_DMA_CHX_STATUS_FBE OSI_BIT(12) -#define MGBE_DMA_CHX_STATUS_TI OSI_BIT(0) -#define MGBE_DMA_CHX_STATUS_RI OSI_BIT(6) -#define MGBE_MAC_PFR_PR OSI_BIT(0) -#define MGBE_MAC_PFR_HUC OSI_BIT(1) -#define MGBE_MAC_PFR_DAIF OSI_BIT(3) -#define MGBE_MAC_PFR_PM OSI_BIT(4) -#define MGBE_MAC_PFR_DBF OSI_BIT(5) -#define MGBE_MAC_PFR_PCF (OSI_BIT(6) | OSI_BIT(7)) -#define MGBE_MAC_PFR_SAIF OSI_BIT(8) -#define MGBE_MAC_PFR_SAF OSI_BIT(9) -#define MGBE_MAC_PFR_HPF OSI_BIT(10) -#define MGBE_MAC_PFR_VTFE OSI_BIT(16) -#define MGBE_MAC_PFR_VTFE_SHIFT 16 -#define MGBE_MAC_PFR_IPFE OSI_BIT(20) -#define MGBE_MAC_PFR_IPFE_SHIFT 20 -#define MGBE_MAC_PFR_DNTU OSI_BIT(21) -#define MGBE_MAC_PFR_VUCC OSI_BIT(22) -#define MGBE_MAC_PFR_RA OSI_BIT(31) -#define MGBE_MAC_ADDRH_AE OSI_BIT(31) -#define MGBE_MAC_ADDRH_AE_SHIFT 31 -#define MGBE_MAC_ADDRH_SA OSI_BIT(30) -#define MGBE_MAC_ADDRH_SA_SHIFT 30 -#define MGBE_MAB_ADDRH_MBC_MAX_MASK 0x3FU -#define MGBE_MAC_ADDRH_MBC (OSI_BIT(29) | OSI_BIT(28) | \ - OSI_BIT(27) | OSI_BIT(26) | \ - OSI_BIT(25) | OSI_BIT(24)) -#define MGBE_MAC_ADDRH_MBC_SHIFT 24 -#define MGBE_MAC_ADDRH_DCS (OSI_BIT(23) | OSI_BIT(22) | \ - OSI_BIT(21) | OSI_BIT(20) | \ - OSI_BIT(19) | OSI_BIT(18) | \ - OSI_BIT(17) | OSI_BIT(16)) -#define MGBE_MAC_ADDRH_DCS_SHIFT 16 -#define MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM (OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15)) -#define MGBE_MAC_L3L4_ADDR_CTR_IDDR_FNUM_SHIFT 12 -#define MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11)) -#define MGBE_MAC_L3L4_ADDR_CTR_IDDR_FTYPE_SHIFT 8 -#define MGBE_MAC_L3L4_ADDR_CTR_TT OSI_BIT(1) -#define MGBE_MAC_L3L4_ADDR_CTR_XB OSI_BIT(0) -#define MGBE_MAC_VLAN_TR_ETV OSI_BIT(16) -#define MGBE_MAC_VLAN_TR_VTIM OSI_BIT(17) -#define MGBE_MAC_VLAN_TR_VTIM_SHIFT 17 -#define MGBE_MAC_VLAN_TR_VTHM OSI_BIT(25) -#define MGBE_MAC_VLANTR_EVLS_ALWAYS_STRIP ((unsigned int)0x3 << 21U) -#define MGBE_MAC_VLANTR_EVLRXS OSI_BIT(24) -#define MGBE_MAC_VLANTR_DOVLTC OSI_BIT(20) -#define MGBE_MAC_VLANTIR_VLTI OSI_BIT(20) -#define MGBE_MAC_VLANTIRR_CSVL OSI_BIT(19) -#define MGBE_MAC_LPI_CSR_LPITE OSI_BIT(20) -#define MGBE_MAC_LPI_CSR_LPITXA OSI_BIT(19) -#define MGBE_MAC_LPI_CSR_PLS OSI_BIT(17) -#define MGBE_MAC_LPI_CSR_LPIEN OSI_BIT(16) -#define MGBE_MAC_RSS_CTRL_RSSE OSI_BIT(0) -#define MGBE_MAC_RSS_CTRL_IP2TE OSI_BIT(1) -#define MGBE_MAC_RSS_CTRL_TCP4TE OSI_BIT(2) -#define MGBE_MAC_RSS_CTRL_UDP4TE OSI_BIT(3) -#define MGBE_MAC_RSS_ADDR_ADDRT OSI_BIT(2) -#define MGBE_MAC_RSS_ADDR_RSSIA_SHIFT 8U -#define MGBE_MAC_RSS_ADDR_OB OSI_BIT(0) -#define MGBE_MAC_RSS_ADDR_CT OSI_BIT(1) -#define MGBE_MAC_TX_TJT OSI_BIT(0) -#define MGBE_MAC_TX_IHE OSI_BIT(12) -#define MGBE_MAC_TX_PCE OSI_BIT(13) -/* DMA SBUS */ -#define MGBE_DMA_SBUS_UNDEF OSI_BIT(0) -#define MGBE_DMA_SBUS_BLEN256 OSI_BIT(7) -#define MGBE_DMA_SBUS_EAME OSI_BIT(11) -#define MGBE_DMA_SBUS_RD_OSR_LMT 0x003F0000U -#define MGBE_DMA_SBUS_WR_OSR_LMT 0x3F000000U -#define MGBE_DMA_TX_EDMA_CTRL_TDPS 0x00000005U -#define MGBE_DMA_RX_EDMA_CTRL_RDPS 0x00000005U -#define MGBE_DMA_TX_EDMA_CTRL_TDPS_PRESI 0x00000003U -#define MGBE_DMA_RX_EDMA_CTRL_RDPS_PRESI 0x00000003U -#define MGBE_MAC_TMCR_SS_2_5G (OSI_BIT(31) | OSI_BIT(30)) -#define MGBE_MAC_TMCR_SS_5G (OSI_BIT(31) | OSI_BIT(29)) -#define MGBE_MAC_TMCR_SS_10G (OSI_BIT(31) | OSI_BIT(30) | OSI_BIT(29)) -#define MGBE_MAC_TMCR_TE OSI_BIT(0) -#define MGBE_MAC_RMCR_RE OSI_BIT(0) -#define MGBE_MTL_TXQ_SIZE_SHIFT 16U -#define MGBE_MTL_RXQ_SIZE_SHIFT 16U -#define MGBE_RXQ_TO_DMA_CHAN_MAP0 0x03020100U -#define MGBE_RXQ_TO_DMA_CHAN_MAP1 0x07060504U -#define MGBE_RXQ_TO_DMA_CHAN_MAP2 0x0B0A0908U -#define MGBE_RXQ_TO_DMA_CHAN_MAP3 0x0F0E0D0CU -#define MGBE_RXQ_TO_DMA_MAP_DDMACH 0x80808080U -#define MGBE_MTL_TXQ_SIZE_SHIFT 16U -#define MGBE_MTL_RXQ_SIZE_SHIFT 16U -#define MGBE_MAC_RMCR_GPSL_MSK 0x3FFF0000U -#define MGBE_MTL_RXQ_OP_MODE_FEP OSI_BIT(4) -#define MGBE_MAC_TCR_TSCFUPDT OSI_BIT(1) -#define MGBE_MAC_TCR_TSINIT OSI_BIT(2) -#define MGBE_MAC_TCR_TSUPDT OSI_BIT(3) -#define MGBE_MAC_TCR_TSADDREG OSI_BIT(5) -#define MGBE_MAC_TCR_TSCTRLSSR OSI_BIT(9) -#define MGBE_MAC_TCR_TSENMACADDR OSI_BIT(18) -#define MGBE_MAC_TCR_SNAPTYPSEL_SHIFT 16U -#define MGBE_MAC_STNSUR_ADDSUB_SHIFT 31U -#define MGBE_MAC_SSIR_SSINC_SHIFT 16U -#define MGBE_MAC_STNSR_TSSS_MASK 0x7FFFFFFFU -#define MGBE_MAC_PTO_CR_PTOEN OSI_BIT(0) -#define MGBE_MAC_PTO_CR_ASYNCEN OSI_BIT(1) -#define MGBE_MAC_PTO_CR_APDREQEN OSI_BIT(2) -#define MGBE_MAC_PTO_CR_DN (OSI_BIT(15) | OSI_BIT(14) | \ - OSI_BIT(13) | OSI_BIT(12) | \ - OSI_BIT(11) | OSI_BIT(10) | \ - OSI_BIT(9) | OSI_BIT(8)) -#define MGBE_MAC_PTO_CR_DN_SHIFT 8U -#define MGBE_MAC_PIDR_PID_MASK 0XFFFFU -#define MGBE_MAC_QX_TX_FLW_CTRL_TFE OSI_BIT(1) -#define MGBE_MAC_RX_FLW_CTRL_RFE OSI_BIT(0) -#define MGBE_MAC_PAUSE_TIME 0xFFFF0000U -#define MGBE_MAC_PAUSE_TIME_MASK 0xFFFF0000U -#define MGBE_MTL_RXQ_OP_MODE_EHFC OSI_BIT(7) -#define MGBE_MTL_RXQ_OP_MODE_RFA_SHIFT 1U -#define MGBE_MTL_RXQ_OP_MODE_RFA_MASK 0x0000007EU -#define MGBE_MTL_RXQ_OP_MODE_RFD_SHIFT 17U -#define MGBE_MTL_RXQ_OP_MODE_RFD_MASK 0x007E0000U -/* MAC FPE control/statusOSI_BITmap */ -#define MGBE_MAC_FPE_CTS_EFPE OSI_BIT(0) -#define MGBE_MAC_FPE_CTS_TRSP OSI_BIT(19) -#define MGBE_MAC_FPE_CTS_TVER OSI_BIT(18) -#define MGBE_MAC_FPE_CTS_RRSP OSI_BIT(17) -#define MGBE_MAC_FPE_CTS_RVER OSI_BIT(16) -#define MGBE_MAC_FPE_CTS_SVER OSI_BIT(1) -#define MGBE_MAC_FPE_CTS_SRSP OSI_BIT(2) -/* MTL_FPE_CTRL_STS */ -#define MGBE_MTL_FPE_CTS_PEC (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11) | \ - OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15)) -#define MGBE_MTL_FPE_CTS_PEC_SHIFT 8U -#define MGBE_MTL_FPE_CTS_PEC_MAX_SHIFT 16U -/* MTL FPE adv registers */ -#define MGBE_MTL_FPE_ADV_HADV_MASK (0xFFFFU) -#define MGBE_MTL_FPE_ADV_HADV_VAL 100U -/* MTL_EST_CONTROL */ -#define MGBE_MTL_EST_CONTROL_PTOV (OSI_BIT(23) | OSI_BIT(24) | \ - OSI_BIT(25) | OSI_BIT(26) | \ - OSI_BIT(27) | OSI_BIT(28) | \ - OSI_BIT(29) | OSI_BIT(30) | \ - OSI_BIT(31)) -#define MGBE_MTL_EST_CONTROL_PTOV_SHIFT 23U -#define MGBE_MTL_EST_PTOV_RECOMMEND 32U -#define MGBE_MTL_EST_CONTROL_CTOV (OSI_BIT(11) | OSI_BIT(12) | \ - OSI_BIT(13) | OSI_BIT(14) | \ - OSI_BIT(15) | OSI_BIT(16) | \ - OSI_BIT(17) | OSI_BIT(18) | \ - OSI_BIT(19) | OSI_BIT(20) | \ - OSI_BIT(21) | OSI_BIT(22)) -#define MGBE_MTL_EST_CONTROL_CTOV_SHIFT 11U -#define MGBE_MTL_EST_CTOV_RECOMMEND 42U -#define MGBE_8PTP_CYCLE 26U -#ifdef MACSEC_SUPPORT -/** - * MACSEC Recommended value - * By default PCS and UPHY are present - */ -#define MGBE_MTL_EST_CTOV_MACSEC_RECOMMEND 295U -#endif /* MACSEC_SUPPORT */ -#define MGBE_MTL_EST_CONTROL_TILS (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10)) -#define MGBE_MTL_EST_CONTROL_LCSE (OSI_BIT(7) | OSI_BIT(6)) -#define MGBE_MTL_EST_CONTROL_LCSE_VAL 0U -#define MGBE_MTL_EST_CONTROL_LCSE_SHIFT 6U -#define MGBE_MTL_EST_CONTROL_DDBF OSI_BIT(4) -#define MGBE_MTL_EST_CONTROL_SSWL OSI_BIT(1) -#define MGBE_MTL_EST_OVERHEAD_OVHD (OSI_BIT(0) | OSI_BIT(1) | \ - OSI_BIT(2) | OSI_BIT(3) | \ - OSI_BIT(4) | OSI_BIT(5)) -#define MGBE_MTL_EST_OVERHEAD_RECOMMEND 56U -/* EST controlOSI_BITmap */ -#define MGBE_MTL_EST_EEST OSI_BIT(0) -#define MGBE_MTL_EST_SSWL OSI_BIT(1) -#define MGBE_MTL_EST_QHLBF OSI_BIT(3) -/* EST GCL controlOSI_BITmap */ -#define MGBE_MTL_EST_ADDR_SHIFT 8 -#define MGBE_MTL_EST_ADDR_MASK (OSI_BIT(8) | OSI_BIT(9) | \ - OSI_BIT(10) | OSI_BIT(11) | \ - OSI_BIT(12) | OSI_BIT(13) | \ - OSI_BIT(14) | OSI_BIT(15) | \ - OSI_BIT(16) | OSI_BIT(17) | \ - OSI_BIT(18) | OSI_BIT(19)) -#define MGBE_MTL_EST_SRWO OSI_BIT(0) -#define MGBE_MTL_EST_GCRR OSI_BIT(2) -#define MGBE_MTL_EST_ERR0 OSI_BIT(20) -/* EST GCRA addresses */ -#define MGBE_MTL_EST_BTR_LOW ((unsigned int)0x0 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_BTR_HIGH ((unsigned int)0x1 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_LOW ((unsigned int)0x2 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH ((unsigned int)0x3 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_CTR_HIGH_MAX 0xFFU -#define MGBE_MTL_EST_TER ((unsigned int)0x4 << \ - MGBE_MTL_EST_ADDR_SHIFT) -#define MGBE_MTL_EST_LLR ((unsigned int)0x5 << \ - MGBE_MTL_EST_ADDR_SHIFT) -/*EST MTL interrupt STATUS and ERR*/ -#define MGBE_MTL_IS_ESTIS OSI_BIT(18) -/* MTL_EST_STATUS*/ -#define MGBE_MTL_EST_STATUS_CGCE OSI_BIT(4) -#define MGBE_MTL_EST_STATUS_HLBS OSI_BIT(3) -#define MGBE_MTL_EST_STATUS_HLBF OSI_BIT(2) -#define MGBE_MTL_EST_STATUS_BTRE OSI_BIT(1) -#define MGBE_MTL_EST_STATUS_SWLC OSI_BIT(0) -#define MGBE_MTL_EST_ITRE_CGCE OSI_BIT(4) -#define MGBE_MTL_EST_ITRE_IEHS OSI_BIT(3) -#define MGBE_MTL_EST_ITRE_IEHF OSI_BIT(2) -#define MGBE_MTL_EST_ITRE_IEBE OSI_BIT(1) -#define MGBE_MTL_EST_ITRE_IECC OSI_BIT(0) - -#define MGBE_MAC_EXT_CNF_DDS OSI_BIT(7) -#define MGBE_MAC_EXT_CNF_EIPG 0x1U -#define MGBE_MAC_EXT_CNF_EIPG_MASK 0x7FU -/* TX timestamp */ -#define MGBE_MAC_TSS_TXTSC OSI_BIT(15) -#define MGBE0_SID ((nveu32_t)0x6U) -#define MGBE1_SID ((nveu32_t)0x49U) -#define MGBE2_SID ((nveu32_t)0x4AU) -#define MGBE3_SID ((nveu32_t)0x4BU) -#define MGBE_SID_VAL1(x) (((x) << 24U) |\ - ((x) << 16U) |\ - ((x) << 8U) |\ - (x)) -#define MGBE_SID_VAL2(x) (((x) << 8U) |\ - (x)) -/** @} */ - -/** - * @addtogroup MGBE-QUEUE QUEUE fifo size programmable values - * - * @brief Queue FIFO size programmable values - * @{ - */ -/* Formula is "Programmed value = (x + 1 )*256" - * Total Rx buf size is 192KB so 192*1024 = (x + 1)*256 - * which gives x as 0x2FF - */ -#define MGBE_19K 0x4BU /* For Ten MTL queues */ -#define MGBE_21K 0x53U /* For Nine MTL queues */ -#define MGBE_24K 0x5FU /* For Eight MTL queues */ -#define MGBE_27K 0x6BU /* For Seven MTL queues */ -#define MGBE_32K 0x7FU /* For Six MTL queues */ -#define MGBE_38K 0x97U /* For Five MTL queues */ -#define MGBE_48K 0xBFU /* For Four MTL queues */ -#define MGBE_64K 0xFFU /* For Three MTL queues */ -#define MGBE_96K 0x17FU /* For Two MTL queues */ -#define MGBE_192K 0x2FFU /* For One MTL queue */ -/** @} */ - -/** - * @addtogroup MGBE-SIZE SIZE calculation helper Macros - * - * @brief SIZE calculation defines - * @{ - */ -#define FIFO_SIZE_B(x) (x) -#define FIFO_SIZE_KB(x) ((x) * 1024U) -/** @} */ - -/** - * @addtogroup MGBE-QSIZE Queue SIZE Mapping Macros - * - * @brief Tx and Rx Queue SIZE Mapping defines - * @{ - */ -#define MGBE_TX_FIFO_SIZE_64KB 9U -#define MGBE_RX_FIFO_SIZE_64KB 9U -#define MGBE_TX_FIFO_SIZE_128KB 10U -#define MGBE_RX_FIFO_SIZE_192KB 12U -/** @} */ - -/** - * @addtogroup MGBE-HW-BACKUP - * - * @brief Definitions related to taking backup of MGBE core registers. - * @{ - */ - -/* Hardware Register offsets to be backed up during suspend. - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before MGBE_MAX_MAC_BAK_IDX, and - * update MGBE_MAX_MAC_BAK_IDX based on new macro. - */ -#define MGBE_MAC_TMCR_BAK_IDX 0U -#define MGBE_MAC_RMCR_BAK_IDX ((MGBE_MAC_TMCR_BAK_IDX + 1U)) -#define MGBE_MAC_PFR_BAK_IDX ((MGBE_MAC_RMCR_BAK_IDX + 1U)) -#define MGBE_MAC_VLAN_TAG_BAK_IDX ((MGBE_MAC_PFR_BAK_IDX + 1U)) -#define MGBE_MAC_VLANTIR_BAK_IDX ((MGBE_MAC_VLAN_TAG_BAK_IDX + 1U)) -#define MGBE_MAC_RX_FLW_CTRL_BAK_IDX ((MGBE_MAC_VLANTIR_BAK_IDX + 1U)) -#define MGBE_MAC_RQC0R_BAK_IDX ((MGBE_MAC_RX_FLW_CTRL_BAK_IDX + 1U)) -#define MGBE_MAC_RQC1R_BAK_IDX ((MGBE_MAC_RQC0R_BAK_IDX + 1U)) -#define MGBE_MAC_RQC2R_BAK_IDX ((MGBE_MAC_RQC1R_BAK_IDX + 1U)) -#define MGBE_MAC_ISR_BAK_IDX ((MGBE_MAC_RQC2R_BAK_IDX + 1U)) -#define MGBE_MAC_IER_BAK_IDX ((MGBE_MAC_ISR_BAK_IDX + 1U)) -#define MGBE_MAC_PMTCSR_BAK_IDX ((MGBE_MAC_IER_BAK_IDX + 1U)) -#define MGBE_MAC_LPI_CSR_BAK_IDX ((MGBE_MAC_PMTCSR_BAK_IDX + 1U)) -#define MGBE_MAC_LPI_TIMER_CTRL_BAK_IDX ((MGBE_MAC_LPI_CSR_BAK_IDX + 1U)) -#define MGBE_MAC_LPI_EN_TIMER_BAK_IDX ((MGBE_MAC_LPI_TIMER_CTRL_BAK_IDX + 1U)) -#define MGBE_MAC_EXT_CNF_BAK_IDX ((MGBE_MAC_LPI_EN_TIMER_BAK_IDX + 1U)) -#define MGBE_MAC_TCR_BAK_IDX ((MGBE_MAC_EXT_CNF_BAK_IDX + 1U)) -#define MGBE_MAC_SSIR_BAK_IDX ((MGBE_MAC_TCR_BAK_IDX + 1U)) -#define MGBE_MAC_STSR_BAK_IDX ((MGBE_MAC_SSIR_BAK_IDX + 1U)) -#define MGBE_MAC_STNSR_BAK_IDX ((MGBE_MAC_STSR_BAK_IDX + 1U)) -#define MGBE_MAC_STSUR_BAK_IDX ((MGBE_MAC_STNSR_BAK_IDX + 1U)) -#define MGBE_MAC_STNSUR_BAK_IDX ((MGBE_MAC_STSUR_BAK_IDX + 1U)) -#define MGBE_MAC_TAR_BAK_IDX ((MGBE_MAC_STNSUR_BAK_IDX + 1U)) -#define MGBE_DMA_BMR_BAK_IDX ((MGBE_MAC_TAR_BAK_IDX + 1U)) -#define MGBE_DMA_SBUS_BAK_IDX ((MGBE_DMA_BMR_BAK_IDX + 1U)) -#define MGBE_DMA_ISR_BAK_IDX ((MGBE_DMA_SBUS_BAK_IDX + 1U)) -#define MGBE_MTL_OP_MODE_BAK_IDX ((MGBE_DMA_ISR_BAK_IDX + 1U)) -#define MGBE_MTL_RXQ_DMA_MAP0_BAK_IDX ((MGBE_MTL_OP_MODE_BAK_IDX + 1U)) -/* x varies from 0-3, 4 HTR registers total */ -#define MGBE_MAC_HTR_REG_BAK_IDX(x) ((MGBE_MTL_RXQ_DMA_MAP0_BAK_IDX + 1U + \ - (x))) -/* x varies from 0-9, 10 queues total */ -#define MGBE_MAC_QX_TX_FLW_CTRL_BAK_IDX(x) ((MGBE_MAC_HTR_REG_BAK_IDX(0U) \ - + MGBE_MAX_HTR_REGS + (x))) -/* x varies from 0-31, 32 L2 DA/SA filters total */ -#define MGBE_MAC_ADDRH_BAK_IDX(x) ((MGBE_MAC_QX_TX_FLW_CTRL_BAK_IDX(0U) \ - + OSI_MGBE_MAX_NUM_QUEUES + (x))) -#define MGBE_MAC_ADDRL_BAK_IDX(x) ((MGBE_MAC_ADDRH_BAK_IDX(0U) + \ - OSI_MGBE_MAX_MAC_ADDRESS_FILTER + (x))) -/* MTL HW Register offsets - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before MGBE_MAX_MTL_BAK_IDX, and - * update MGBE_MAX_MTL_BAK_IDX based on new macro. - */ -/* x varies from 0-9, 10 queues total */ -#define MGBE_MTL_CHX_TX_OP_MODE_BAK_IDX(x) ((MGBE_MAC_ADDRL_BAK_IDX(0U) + \ - OSI_MGBE_MAX_MAC_ADDRESS_FILTER + \ - (x))) -#define MGBE_MTL_TXQ_ETS_CR_BAK_IDX(x) ((MGBE_MTL_CHX_TX_OP_MODE_BAK_IDX(0U) \ - + OSI_MGBE_MAX_NUM_QUEUES + (x))) -#define MGBE_MTL_TXQ_QW_BAK_IDX(x) ((MGBE_MTL_TXQ_ETS_CR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_NUM_QUEUES + (x))) -#define MGBE_MTL_TXQ_ETS_SSCR_BAK_IDX(x) ((MGBE_MTL_TXQ_QW_BAK_IDX(0U) \ - + OSI_MGBE_MAX_NUM_QUEUES + \ - (x))) -#define MGBE_MTL_TXQ_ETS_HCR_BAK_IDX(x) ((MGBE_MTL_TXQ_ETS_SSCR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_NUM_QUEUES + (x))) -#define MGBE_MTL_TXQ_ETS_LCR_BAK_IDX(x) ((MGBE_MTL_TXQ_ETS_HCR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_NUM_QUEUES + (x))) -#define MGBE_MTL_CHX_RX_OP_MODE_BAK_IDX(x) \ - ((MGBE_MTL_TXQ_ETS_LCR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_NUM_QUEUES + (x))) - -/* MGBE Wrapper register offsets to be saved during suspend - * - * Do not change the order of these macros. To add new registers to be - * backed up, append to end of list before MGBE_MAX_WRAPPER_BAK_IDX, - * and update MGBE_MAX_WRAPPER_BAK_IDX based on new macro. - */ -#define MGBE_CLOCK_CTRL_0_BAK_IDX ((MGBE_MTL_CHX_RX_OP_MODE_BAK_IDX(0U) \ - + OSI_MGBE_MAX_NUM_QUEUES)) -#define MGBE_AXI_ASID_CTRL_BAK_IDX ((MGBE_CLOCK_CTRL_0_BAK_IDX + 1U)) -#define MGBE_PAD_CRTL_BAK_IDX ((MGBE_AXI_ASID_CTRL_BAK_IDX + 1U)) -#define MGBE_PAD_AUTO_CAL_CFG_BAK_IDX ((MGBE_PAD_CRTL_BAK_IDX + 1U)) -/* MGBE_PAD_AUTO_CAL_STAT is Read-only. Skip backup/restore */ - -/* To add new direct access registers to backup during suspend, - * and restore during resume add it before this line, and increment - * MGBE_DIRECT_MAX_BAK_IDX accordingly. - */ -#define MGBE_DIRECT_MAX_BAK_IDX ((MGBE_PAD_AUTO_CAL_CFG_BAK_IDX + 1U)) - -/** - * Start indirect addressing registers - **/ -/* x varies from 0-7, 8 L3/L4 filters total */ -#define MGBE_MAC_L3L4_CTR_BAK_IDX(x) (MGBE_DIRECT_MAX_BAK_IDX + (x)) -#define MGBE_MAC_L4_ADR_BAK_IDX(x) ((MGBE_MAC_L3L4_CTR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) -#define MGBE_MAC_L3_AD0R_BAK_IDX(x) ((MGBE_MAC_L4_ADR_BAK_IDX(0U) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) -#define MGBE_MAC_L3_AD1R_BAK_IDX(x) ((MGBE_MAC_L3_AD0R_BAK_IDX(0U) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) -#define MGBE_MAC_L3_AD2R_BAK_IDX(x) ((MGBE_MAC_L3_AD1R_BAK_IDX(0U) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) -#define MGBE_MAC_L3_AD3R_BAK_IDX(x) ((MGBE_MAC_L3_AD2R_BAK_IDX(0U) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) - -/* x varies from 0-31, 32 VLAN tag filters total */ -#define MGBE_MAC_VLAN_BAK_IDX(x) ((MGBE_MAC_L3_AD3R_BAK_IDX(0) + \ - OSI_MGBE_MAX_L3_L4_FILTER + (x))) -/* Add MAC_DChSel_IndReg */ -#define MGBE_MAC_DCHSEL_BAK_IDX(x) ((MGBE_MAC_VLAN_BAK_IDX(0) + \ - MGBE_MAX_VLAN_FILTER + 1U)) - -#define MGBE_MAX_BAK_IDX ((MGBE_MAC_DCHSEL_BAK_IDX(0) + \ - OSI_MGBE_MAX_MAC_ADDRESS_FILTER + 1U)) -/** @} */ - -/** - * @addtogroup MGBE-MAC MGBE MAC HW feature registers - * - * @brief Helps in identifying the features that are set in MAC HW - * @{ - */ -#define MGBE_MAC_HFR0 0x11C -#define MGBE_MAC_HFR1 0x120 -#define MGBE_MAC_HFR2 0x124 -#define MGBE_MAC_HFR3 0x128 -/** @} */ - -/** - * @addtogroup MGBE-MAC-Feature MGBE MAC HW feature registers bit fields - * - * @brief HW feature register bit masks and bit shifts. - * @{ - */ -#define MGBE_MAC_HFR0_RGMIISEL_MASK 0x1U -#define MGBE_MAC_HFR0_RGMIISEL_SHIFT 0U - -#define MGBE_MAC_HFR0_GMIISEL_MASK 0x1U -#define MGBE_MAC_HFR0_GMIISEL_SHIFT 1U - -#define MGBE_MAC_HFR0_RMIISEL_MASK 0x1U -#define MGBE_MAC_HFR0_RMIISEL_SHIFT 2U - -#define MGBE_MAC_HFR0_HDSEL_MASK 0x1U -#define MGBE_MAC_HFR0_HDSEL_SHIFT 3U - -#define MGBE_MAC_HFR0_VLHASH_MASK 0x1U -#define MGBE_MAC_HFR0_VLHASH_SHIFT 4U - -#define MGBE_MAC_HFR0_SMASEL_MASK 0x1U -#define MGBE_MAC_HFR0_SMASEL_SHIFT 5U - -#define MGBE_MAC_HFR0_RWKSEL_MASK 0x1U -#define MGBE_MAC_HFR0_RWKSEL_SHIFT 6U - -#define MGBE_MAC_HFR0_MGKSEL_MASK 0x1U -#define MGBE_MAC_HFR0_MGKSEL_SHIFT 7U - -#define MGBE_MAC_HFR0_MMCSEL_MASK 0x1U -#define MGBE_MAC_HFR0_MMCSEL_SHIFT 8U - -#define MGBE_MAC_HFR0_ARPOFFLDEN_MASK 0x1U -#define MGBE_MAC_HFR0_ARPOFFLDEN_SHIFT 9U - -#define MGBE_MAC_HFR0_RAVSEL_MASK 0x1U -#define MGBE_MAC_HFR0_RAVSEL_SHIFT 10U - -#define MGBE_MAC_HFR0_AVSEL_MASK 0x1U -#define MGBE_MAC_HFR0_AVSEL_SHIFT 11U - -#define MGBE_MAC_HFR0_TSSSEL_MASK 0x1U -#define MGBE_MAC_HFR0_TSSSEL_SHIFT 12U - -#define MGBE_MAC_HFR0_EEESEL_MASK 0x1U -#define MGBE_MAC_HFR0_EEESEL_SHIFT 13U - -#define MGBE_MAC_HFR0_TXCOESEL_MASK 0x1U -#define MGBE_MAC_HFR0_TXCOESEL_SHIFT 14U - -#define MGBE_MAC_HFR0_RXCOESEL_MASK 0x1U -#define MGBE_MAC_HFR0_RXCOESEL_SHIFT 16U - -#define MGBE_MAC_HFR0_ADDMACADRSEL_MASK 0x1FU -#define MGBE_MAC_HFR0_ADDMACADRSEL_SHIFT 18U - -#define MGBE_MAC_HFR0_PHYSEL_MASK 0x3U -#define MGBE_MAC_HFR0_PHYSEL_SHIFT 23U - -#define MGBE_MAC_HFR0_TSSTSSEL_MASK 0x3U -#define MGBE_MAC_HFR0_TSSTSSEL_SHIFT 25U - -#define MGBE_MAC_HFR0_SAVLANINS_MASK 0x1U -#define MGBE_MAC_HFR0_SAVLANINS_SHIFT 27U - -#define MGBE_MAC_HFR0_VXN_MASK 0x1U -#define MGBE_MAC_HFR0_VXN_SHIFT 29U - -#define MGBE_MAC_HFR0_EDIFFC_MASK 0x1U -#define MGBE_MAC_HFR0_EDIFFC_SHIFT 30U - -#define MGBE_MAC_HFR0_EDMA_MASK 0x1U -#define MGBE_MAC_HFR0_EDMA_SHIFT 31U - -#define MGBE_MAC_HFR1_RXFIFOSIZE_MASK 0x1FU -#define MGBE_MAC_HFR1_RXFIFOSIZE_SHIFT 0U - -#define MGBE_MAC_HFR1_PFCEN_MASK 0x1U -#define MGBE_MAC_HFR1_PFCEN_SHIFT 5U - -#define MGBE_MAC_HFR1_TXFIFOSIZE_MASK 0x1FU -#define MGBE_MAC_HFR1_TXFIFOSIZE_SHIFT 6U - -#define MGBE_MAC_HFR1_OSTEN_MASK 0x1U -#define MGBE_MAC_HFR1_OSTEN_SHIFT 11U - -#define MGBE_MAC_HFR1_PTOEN_MASK 0x1U -#define MGBE_MAC_HFR1_PTOEN_SHIFT 12U - -#define MGBE_MAC_HFR1_ADVTHWORD_MASK 0x1U -#define MGBE_MAC_HFR1_ADVTHWORD_SHIFT 13U - -#define MGBE_MAC_HFR1_ADDR64_MASK 0x3U -#define MGBE_MAC_HFR1_ADDR64_SHIFT 14U - -#define MGBE_MAC_HFR1_DCBEN_MASK 0x1U -#define MGBE_MAC_HFR1_DCBEN_SHIFT 16U - -#define MGBE_MAC_HFR1_SPHEN_MASK 0x1U -#define MGBE_MAC_HFR1_SPHEN_SHIFT 17U - -#define MGBE_MAC_HFR1_TSOEN_MASK 0x1U -#define MGBE_MAC_HFR1_TSOEN_SHIFT 18U - -#define MGBE_MAC_HFR1_DBGMEMA_MASK 0x1U -#define MGBE_MAC_HFR1_DBGMEMA_SHIFT 19U - -#define MGBE_MAC_HFR1_RSSEN_MASK 0x1U -#define MGBE_MAC_HFR1_RSSEN_SHIFT 20U - -#define MGBE_MAC_HFR1_NUMTC_MASK 0x7U -#define MGBE_MAC_HFR1_NUMTC_SHIFT 21U - -#define MGBE_MAC_HFR1_HASHTBLSZ_MASK 0x3U -#define MGBE_MAC_HFR1_HASHTBLSZ_SHIFT 24U - -#define MGBE_MAC_HFR1_L3L4FNUM_MASK 0xFU -#define MGBE_MAC_HFR1_L3L4FNUM_SHIFT 27U - -#define MGBE_MAC_HFR2_RXQCNT_MASK 0xFU -#define MGBE_MAC_HFR2_RXQCNT_SHIFT 0U - -#define MGBE_MAC_HFR2_TXQCNT_MASK 0xFU -#define MGBE_MAC_HFR2_TXQCNT_SHIFT 6U - -#define MGBE_MAC_HFR2_RXCHCNT_MASK 0xFU -#define MGBE_MAC_HFR2_RXCHCNT_SHIFT 12U - -#define MGBE_MAC_HFR2_TXCHCNT_MASK 0xFU -#define MGBE_MAC_HFR2_TXCHCNT_SHIFT 18U - -#define MGBE_MAC_HFR2_PPSOUTNUM_MASK 0x7U -#define MGBE_MAC_HFR2_PPSOUTNUM_SHIFT 24U - -#define MGBE_MAC_HFR2_AUXSNAPNUM_MASK 0x7U -#define MGBE_MAC_HFR2_AUXSNAPNUM_SHIFT 28U - -#define MGBE_MAC_HFR3_NRVF_MASK 0x7U -#define MGBE_MAC_HFR3_NRVF_SHIFT 0U - -#define MGBE_MAC_HFR3_FRPSEL_MASK 0x1U -#define MGBE_MAC_HFR3_FRPSEL_SHIFT 3U - -#define MGBE_MAC_HFR3_CBTISEL_MASK 0x1U -#define MGBE_MAC_HFR3_CBTISEL_SHIFT 4U - -#define MGBE_MAC_HFR3_FRPPIPE_MASK 0x7U -#define MGBE_MAC_HFR3_FRPPIPE_SHIFT 5U - -#define MGBE_MAC_HFR3_POUOST_MASK 0x1U -#define MGBE_MAC_HFR3_POUOST_SHIFT 8U - -#define MGBE_MAC_HFR3_FRPPB_MASK 0x3U -#define MGBE_MAC_HFR3_FRPPB_SHIFT 9U - -#define MGBE_MAC_HFR3_FRPES_MASK 0x3U -#define MGBE_MAC_HFR3_FRPES_SHIFT 11U - -#define MGBE_MAC_HFR3_DVLAN_MASK 0x1U -#define MGBE_MAC_HFR3_DVLAN_SHIFT 13U - -#define MGBE_MAC_HFR3_ASP_MASK 0x3U -#define MGBE_MAC_HFR3_ASP_SHIFT 14U - -#define MGBE_MAC_HFR3_TTSFD_MASK 0x7U -#define MGBE_MAC_HFR3_TTSFD_SHIFT 16U - -#define MGBE_MAC_HFR3_ESTSEL_MASK 0x1U -#define MGBE_MAC_HFR3_ESTSEL_SHIFT 19U - -#define MGBE_MAC_HFR3_GCLDEP_MASK 0x7U -#define MGBE_MAC_HFR3_GCLDEP_SHIFT 20U - -#define MGBE_MAC_HFR3_GCLWID_MASK 0x3U -#define MGBE_MAC_HFR3_GCLWID_SHIFT 23U - -#define MGBE_MAC_HFR3_FPESEL_MASK 0x1U -#define MGBE_MAC_HFR3_FPESEL_SHIFT 26U - -#define MGBE_MAC_HFR3_TBSSEL_MASK 0x1U -#define MGBE_MAC_HFR3_TBSSEL_SHIFT 27U - -#define MGBE_MAC_HFR3_TBS_CH_MASK 0xFU -#define MGBE_MAC_HFR3_TBS_CH_SHIFT 28U - -/* FRP defines */ -#define MGBE_MAC_FRPPB_64 0U -#define MGBE_MAC_FRPPB_128 1U -#define MGBE_MAC_FRPPB_256 2U -#define MGBE_MAC_FRPES_64 0U -#define MGBE_MAC_FRPES_128 1U -#define MGBE_MAC_FRPES_256 2U - -#define MGBE_MAC_FRP_BYTES64 64U -#define MGBE_MAC_FRP_BYTES128 128U -#define MGBE_MAC_FRP_BYTES256 256U -/** @} */ - -#ifdef HSI_SUPPORT -/** - * @addtogroup MGBE-HSI - * - * @brief HSI feature related registers and bitmap - * @{ - */ -#define MGBE_MTL_ECC_INTERRUPT_ENABLE 0x10C8U -#define MGBE_MTL_TXCEIE OSI_BIT(0) -#define MGBE_MTL_RXCEIE OSI_BIT(4) -#define MGBE_MTL_GCEIE OSI_BIT(8) -#define MGBE_MTL_RPCEIE OSI_BIT(12) -#define MGBE_DMA_ECC_INTERRUPT_ENABLE 0x3068U -#define MGBE_DMA_TCEIE OSI_BIT(0) -#define MGBE_DMA_DCEIE OSI_BIT(1) -#define MGBE_MAC_SCSR_CONTROL 0x164U -#define MGBE_CPEN OSI_BIT(0) -#define MGBE_MTL_ECC_INTERRUPT_STATUS 0x10CCU -#define MGBE_DMA_ECC_INTERRUPT_STATUS 0x306CU -#define MGBE_DWCXG_CORE_MAC_FSM_ACT_TIMER 0x15CU -#define MGBE_CTMR_SHIFT 28U -#define MGBE_CTMR_MASK 0x70000000U -#define MGBE_LTMRMD_SHIFT 20U -#define MGBE_LTMRMD_MASK 0xF00000U -#define MGBE_NTMRMD_SHIFT 16U -#define MGBE_NTMRMD_MASK 0xF0000U -#define MGBE_TMR_SHIFT 0U -#define MGBE_TMR_MASK 0x3FFU -#define MGBE_MTL_ECC_CONTROL 0x10C0U -#define MGBE_MTL_ECC_MTXED OSI_BIT(0) -#define MGBE_MTL_ECC_MRXED OSI_BIT(1) -#define MGBE_MTL_ECC_MGCLED OSI_BIT(2) -#define MGBE_MTL_ECC_MRXPED OSI_BIT(3) -#define MGBE_MTL_ECC_TSOED OSI_BIT(4) -#define MGBE_MTL_ECC_DESCED OSI_BIT(5) -#define MGBE_MAC_FSM_CONTROL 0x158U -#define MGBE_TMOUTEN OSI_BIT(0) -#define MGBE_PRTYEN OSI_BIT(1) -#define MGBE_MAC_DPP_FSM_INTERRUPT_STATUS 0x150U -#define MGBE_MTL_DPP_CONTROL 0x10E0U -#define MGBE_DDPP OSI_BIT(0) -#define MGBE_MAC_DPP_FSM_INTERRUPT_STATUS 0x150U -/** @} */ -#endif - -#endif /* MGBE_CORE_H_ */ diff --git a/osi/core/mgbe_mmc.c b/osi/core/mgbe_mmc.c deleted file mode 100644 index 75ed121..0000000 --- a/osi/core/mgbe_mmc.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (c) 2020, 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 "../osi/common/common.h" -#include -#include -#include "mgbe_mmc.h" -#include "mgbe_core.h" - -/** - * @brief update_mmc_val - function to read register and return value to callee - * - * Algorithm: Read the registers, check for boundary, if more, reset - * counters else return same to caller. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] last_value: previous value of stats variable. - * @param[in] offset: HW register offset - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - * - * @retval 0 on MMC counters overflow - * @retval value on current MMC counter value. - */ -static inline unsigned long update_mmc_val(struct osi_core_priv_data *osi_core, - unsigned long last_value, - unsigned long offset) -{ - unsigned long temp; - unsigned int value = osi_readl((unsigned char *)osi_core->base + - offset); - - temp = last_value + value; - if (temp < last_value) { - OSI_CORE_ERR(osi_core->osd, - OSI_LOG_ARG_OUTOFBOUND, - "Value overflow resetting all counters\n", - (unsigned long long)offset); - mgbe_reset_mmc(osi_core); - } else { - return temp; - } - - return 0; -} - -/** - * @brief mgbe_reset_mmc - To reset MMC registers and ether_mmc_counter - * structure variable - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - */ -void mgbe_reset_mmc(struct osi_core_priv_data *osi_core) -{ - unsigned int value; - - value = osi_readl((unsigned char *)osi_core->base + MGBE_MMC_CNTRL); - /* self-clear bit in one clock cycle */ - value |= MGBE_MMC_CNTRL_CNTRST; - osi_writel(value, (unsigned char *)osi_core->base + MGBE_MMC_CNTRL); - osi_memset(&osi_core->mmc, 0U, sizeof(struct osi_mmc_counters)); -} - -/** - * @brief mgbe_read_mmc - To read MMC registers and ether_mmc_counter structure - * variable - * - * Algorithm: Pass register offset and old value to helper function and - * update structure. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - */ -void mgbe_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_L); - mmc->mmc_tx_octetcount_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_octetcount_gb_h, - MMC_TXOCTETCOUNT_GB_H); - mmc->mmc_tx_framecount_gb = - update_mmc_val(osi_core, mmc->mmc_tx_framecount_gb, - MMC_TXPACKETCOUNT_GB_L); - mmc->mmc_tx_framecount_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_framecount_gb_h, - MMC_TXPACKETCOUNT_GB_H); - mmc->mmc_tx_broadcastframe_g = - update_mmc_val(osi_core, mmc->mmc_tx_broadcastframe_g, - MMC_TXBROADCASTPACKETS_G_L); - mmc->mmc_tx_broadcastframe_g_h = - update_mmc_val(osi_core, mmc->mmc_tx_broadcastframe_g_h, - MMC_TXBROADCASTPACKETS_G_H); - mmc->mmc_tx_multicastframe_g = - update_mmc_val(osi_core, mmc->mmc_tx_multicastframe_g, - MMC_TXMULTICASTPACKETS_G_L); - mmc->mmc_tx_multicastframe_g_h = - update_mmc_val(osi_core, mmc->mmc_tx_multicastframe_g_h, - MMC_TXMULTICASTPACKETS_G_H); - mmc->mmc_tx_64_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_64_octets_gb, - MMC_TX64OCTETS_GB_L); - mmc->mmc_tx_64_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_64_octets_gb_h, - MMC_TX64OCTETS_GB_H); - mmc->mmc_tx_65_to_127_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_65_to_127_octets_gb, - MMC_TX65TO127OCTETS_GB_L); - mmc->mmc_tx_65_to_127_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_65_to_127_octets_gb_h, - MMC_TX65TO127OCTETS_GB_H); - mmc->mmc_tx_128_to_255_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_128_to_255_octets_gb, - MMC_TX128TO255OCTETS_GB_L); - mmc->mmc_tx_128_to_255_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_128_to_255_octets_gb_h, - MMC_TX128TO255OCTETS_GB_H); - mmc->mmc_tx_256_to_511_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_256_to_511_octets_gb, - MMC_TX256TO511OCTETS_GB_L); - mmc->mmc_tx_256_to_511_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_256_to_511_octets_gb_h, - MMC_TX256TO511OCTETS_GB_H); - mmc->mmc_tx_512_to_1023_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_512_to_1023_octets_gb, - MMC_TX512TO1023OCTETS_GB_L); - mmc->mmc_tx_512_to_1023_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_512_to_1023_octets_gb_h, - MMC_TX512TO1023OCTETS_GB_H); - mmc->mmc_tx_1024_to_max_octets_gb = - update_mmc_val(osi_core, mmc->mmc_tx_1024_to_max_octets_gb, - MMC_TX1024TOMAXOCTETS_GB_L); - mmc->mmc_tx_1024_to_max_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_1024_to_max_octets_gb_h, - MMC_TX1024TOMAXOCTETS_GB_H); - mmc->mmc_tx_unicast_gb = - update_mmc_val(osi_core, mmc->mmc_tx_unicast_gb, - MMC_TXUNICASTPACKETS_GB_L); - mmc->mmc_tx_unicast_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_unicast_gb_h, - MMC_TXUNICASTPACKETS_GB_H); - mmc->mmc_tx_multicast_gb = - update_mmc_val(osi_core, mmc->mmc_tx_multicast_gb, - MMC_TXMULTICASTPACKETS_GB_L); - mmc->mmc_tx_multicast_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_multicast_gb_h, - MMC_TXMULTICASTPACKETS_GB_H); - mmc->mmc_tx_broadcast_gb = - update_mmc_val(osi_core, mmc->mmc_tx_broadcast_gb, - MMC_TXBROADCASTPACKETS_GB_L); - mmc->mmc_tx_broadcast_gb_h = - update_mmc_val(osi_core, mmc->mmc_tx_broadcast_gb_h, - MMC_TXBROADCASTPACKETS_GB_H); - mmc->mmc_tx_underflow_error = - update_mmc_val(osi_core, mmc->mmc_tx_underflow_error, - MMC_TXUNDERFLOWERROR_L); - mmc->mmc_tx_underflow_error_h = - update_mmc_val(osi_core, mmc->mmc_tx_underflow_error_h, - MMC_TXUNDERFLOWERROR_H); - 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_carrier_error, - MMC_TXCARRIERERROR); - mmc->mmc_tx_octetcount_g = - update_mmc_val(osi_core, mmc->mmc_tx_octetcount_g, - MMC_TXOCTETCOUNT_G_L); - mmc->mmc_tx_octetcount_g_h = - update_mmc_val(osi_core, mmc->mmc_tx_octetcount_g_h, - MMC_TXOCTETCOUNT_G_H); - mmc->mmc_tx_framecount_g = - update_mmc_val(osi_core, mmc->mmc_tx_framecount_g, - MMC_TXPACKETSCOUNT_G_L); - mmc->mmc_tx_framecount_g_h = - update_mmc_val(osi_core, mmc->mmc_tx_framecount_g_h, - MMC_TXPACKETSCOUNT_G_H); - mmc->mmc_tx_excessdef = - update_mmc_val(osi_core, mmc->mmc_tx_excessdef, - MMC_TXEXECESS_DEFERRED); - mmc->mmc_tx_pause_frame = - update_mmc_val(osi_core, mmc->mmc_tx_pause_frame, - MMC_TXPAUSEPACKETS_L); - mmc->mmc_tx_pause_frame_h = - update_mmc_val(osi_core, mmc->mmc_tx_pause_frame_h, - MMC_TXPAUSEPACKETS_H); - mmc->mmc_tx_vlan_frame_g = - update_mmc_val(osi_core, mmc->mmc_tx_vlan_frame_g, - MMC_TXVLANPACKETS_G_L); - mmc->mmc_tx_vlan_frame_g_h = - update_mmc_val(osi_core, mmc->mmc_tx_vlan_frame_g_h, - MMC_TXVLANPACKETS_G_H); - mmc->mmc_rx_framecount_gb = - update_mmc_val(osi_core, mmc->mmc_rx_framecount_gb, - MMC_RXPACKETCOUNT_GB_L); - mmc->mmc_rx_framecount_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_framecount_gb_h, - MMC_RXPACKETCOUNT_GB_H); - mmc->mmc_rx_octetcount_gb = - update_mmc_val(osi_core, mmc->mmc_rx_octetcount_gb, - MMC_RXOCTETCOUNT_GB_L); - mmc->mmc_rx_octetcount_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_octetcount_gb_h, - MMC_RXOCTETCOUNT_GB_H); - mmc->mmc_rx_octetcount_g = - update_mmc_val(osi_core, mmc->mmc_rx_octetcount_g, - MMC_RXOCTETCOUNT_G_L); - mmc->mmc_rx_octetcount_g_h = - update_mmc_val(osi_core, mmc->mmc_rx_octetcount_g_h, - MMC_RXOCTETCOUNT_G_H); - mmc->mmc_rx_broadcastframe_g = - update_mmc_val(osi_core, mmc->mmc_rx_broadcastframe_g, - MMC_RXBROADCASTPACKETS_G_L); - mmc->mmc_rx_broadcastframe_g_h = - update_mmc_val(osi_core, mmc->mmc_rx_broadcastframe_g_h, - MMC_RXBROADCASTPACKETS_G_H); - mmc->mmc_rx_multicastframe_g = - update_mmc_val(osi_core, mmc->mmc_rx_multicastframe_g, - MMC_RXMULTICASTPACKETS_G_L); - mmc->mmc_rx_multicastframe_g_h = - update_mmc_val(osi_core, mmc->mmc_rx_multicastframe_g_h, - MMC_RXMULTICASTPACKETS_G_H); - mmc->mmc_rx_crc_error = - update_mmc_val(osi_core, mmc->mmc_rx_crc_error, - MMC_RXCRCERROR_L); - mmc->mmc_rx_crc_error_h = - update_mmc_val(osi_core, mmc->mmc_rx_crc_error_h, - MMC_RXCRCERROR_H); - 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_L); - mmc->mmc_rx_64_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_64_octets_gb_h, - MMC_RX64OCTETS_GB_H); - mmc->mmc_rx_65_to_127_octets_gb = - update_mmc_val(osi_core, mmc->mmc_rx_65_to_127_octets_gb, - MMC_RX65TO127OCTETS_GB_L); - mmc->mmc_rx_65_to_127_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_65_to_127_octets_gb_h, - MMC_RX65TO127OCTETS_GB_H); - mmc->mmc_rx_128_to_255_octets_gb = - update_mmc_val(osi_core, mmc->mmc_rx_128_to_255_octets_gb, - MMC_RX128TO255OCTETS_GB_L); - mmc->mmc_rx_128_to_255_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_128_to_255_octets_gb_h, - MMC_RX128TO255OCTETS_GB_H); - mmc->mmc_rx_256_to_511_octets_gb = - update_mmc_val(osi_core, mmc->mmc_rx_256_to_511_octets_gb, - MMC_RX256TO511OCTETS_GB_L); - mmc->mmc_rx_256_to_511_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_256_to_511_octets_gb_h, - MMC_RX256TO511OCTETS_GB_H); - mmc->mmc_rx_512_to_1023_octets_gb = - update_mmc_val(osi_core, mmc->mmc_rx_512_to_1023_octets_gb, - MMC_RX512TO1023OCTETS_GB_L); - mmc->mmc_rx_512_to_1023_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_512_to_1023_octets_gb_h, - MMC_RX512TO1023OCTETS_GB_H); - mmc->mmc_rx_1024_to_max_octets_gb = - update_mmc_val(osi_core, mmc->mmc_rx_1024_to_max_octets_gb, - MMC_RX1024TOMAXOCTETS_GB_L); - mmc->mmc_rx_1024_to_max_octets_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_1024_to_max_octets_gb_h, - MMC_RX1024TOMAXOCTETS_GB_H); - mmc->mmc_rx_unicast_g = - update_mmc_val(osi_core, mmc->mmc_rx_unicast_g, - MMC_RXUNICASTPACKETS_G_L); - mmc->mmc_rx_unicast_g_h = - update_mmc_val(osi_core, mmc->mmc_rx_unicast_g_h, - MMC_RXUNICASTPACKETS_G_H); - mmc->mmc_rx_length_error = - update_mmc_val(osi_core, mmc->mmc_rx_length_error, - MMC_RXLENGTHERROR_L); - mmc->mmc_rx_length_error_h = - update_mmc_val(osi_core, mmc->mmc_rx_length_error_h, - MMC_RXLENGTHERROR_H); - mmc->mmc_rx_outofrangetype = - update_mmc_val(osi_core, mmc->mmc_rx_outofrangetype, - MMC_RXOUTOFRANGETYPE_L); - mmc->mmc_rx_outofrangetype_h = - update_mmc_val(osi_core, mmc->mmc_rx_outofrangetype_h, - MMC_RXOUTOFRANGETYPE_H); - mmc->mmc_rx_pause_frames = - update_mmc_val(osi_core, mmc->mmc_rx_pause_frames, - MMC_RXPAUSEPACKETS_L); - mmc->mmc_rx_pause_frames_h = - update_mmc_val(osi_core, mmc->mmc_rx_pause_frames_h, - MMC_RXPAUSEPACKETS_H); - mmc->mmc_rx_fifo_overflow = - update_mmc_val(osi_core, mmc->mmc_rx_fifo_overflow, - MMC_RXFIFOOVERFLOW_L); - mmc->mmc_rx_fifo_overflow_h = - update_mmc_val(osi_core, mmc->mmc_rx_fifo_overflow_h, - MMC_RXFIFOOVERFLOW_H); - mmc->mmc_rx_vlan_frames_gb = - update_mmc_val(osi_core, mmc->mmc_rx_vlan_frames_gb, - MMC_RXVLANPACKETS_GB_L); - mmc->mmc_rx_vlan_frames_gb_h = - update_mmc_val(osi_core, mmc->mmc_rx_vlan_frames_gb_h, - MMC_RXVLANPACKETS_GB_H); - mmc->mmc_rx_watchdog_error = - update_mmc_val(osi_core, mmc->mmc_rx_watchdog_error, - MMC_RXWATCHDOGERROR); - mmc->mmc_tx_lpi_usec_cntr = - update_mmc_val(osi_core, mmc->mmc_tx_lpi_usec_cntr, - MMC_TXLPIUSECCNTR); - mmc->mmc_tx_lpi_tran_cntr = - update_mmc_val(osi_core, mmc->mmc_tx_lpi_tran_cntr, - MMC_TXLPITRANCNTR); - mmc->mmc_rx_lpi_usec_cntr = - update_mmc_val(osi_core, mmc->mmc_rx_lpi_usec_cntr, - MMC_RXLPIUSECCNTR); - mmc->mmc_rx_lpi_tran_cntr = - update_mmc_val(osi_core, mmc->mmc_rx_lpi_tran_cntr, - MMC_RXLPITRANCNTR); - mmc->mmc_rx_ipv4_gd = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd, - MMC_RXIPV4_GD_PKTS_L); - mmc->mmc_rx_ipv4_gd_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd_h, - MMC_RXIPV4_GD_PKTS_H); - mmc->mmc_rx_ipv4_hderr = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr, - MMC_RXIPV4_HDRERR_PKTS_L); - mmc->mmc_rx_ipv4_hderr_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr_h, - MMC_RXIPV4_HDRERR_PKTS_H); - mmc->mmc_rx_ipv4_nopay = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay, - MMC_RXIPV4_NOPAY_PKTS_L); - mmc->mmc_rx_ipv4_nopay_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay_h, - MMC_RXIPV4_NOPAY_PKTS_H); - mmc->mmc_rx_ipv4_frag = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag, - MMC_RXIPV4_FRAG_PKTS_L); - mmc->mmc_rx_ipv4_frag_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag_h, - MMC_RXIPV4_FRAG_PKTS_H); - mmc->mmc_rx_ipv4_udsbl = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl, - MMC_RXIPV4_UBSBL_PKTS_L); - mmc->mmc_rx_ipv4_udsbl_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl_h, - MMC_RXIPV4_UBSBL_PKTS_H); - mmc->mmc_rx_ipv6_gd = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd, - MMC_RXIPV6_GD_PKTS_L); - mmc->mmc_rx_ipv6_gd_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_h, - MMC_RXIPV6_GD_PKTS_H); - mmc->mmc_rx_ipv6_hderr = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr, - MMC_RXIPV6_HDRERR_PKTS_L); - mmc->mmc_rx_ipv6_hderr_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_h, - MMC_RXIPV6_HDRERR_PKTS_H); - mmc->mmc_rx_ipv6_nopay = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay, - MMC_RXIPV6_NOPAY_PKTS_L); - mmc->mmc_rx_ipv6_nopay_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_h, - MMC_RXIPV6_NOPAY_PKTS_H); - mmc->mmc_rx_udp_gd = - update_mmc_val(osi_core, mmc->mmc_rx_udp_gd, - MMC_RXUDP_GD_PKTS_L); - mmc->mmc_rx_udp_gd_h = - update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_h, - MMC_RXUDP_GD_PKTS_H); - mmc->mmc_rx_udp_err = - update_mmc_val(osi_core, mmc->mmc_rx_udp_err, - MMC_RXUDP_ERR_PKTS_L); - mmc->mmc_rx_udp_err_h = - update_mmc_val(osi_core, mmc->mmc_rx_udp_err_h, - MMC_RXUDP_ERR_PKTS_H); - mmc->mmc_rx_tcp_gd = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd, - MMC_RXTCP_GD_PKTS_L); - mmc->mmc_rx_tcp_gd_h = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd_h, - MMC_RXTCP_GD_PKTS_H); - mmc->mmc_rx_tcp_err = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_err, - MMC_RXTCP_ERR_PKTS_L); - mmc->mmc_rx_tcp_err_h = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_err_h, - MMC_RXTCP_ERR_PKTS_H); - mmc->mmc_rx_icmp_gd = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd, - MMC_RXICMP_GD_PKTS_L); - mmc->mmc_rx_icmp_gd_h = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd_h, - MMC_RXICMP_GD_PKTS_H); - mmc->mmc_rx_icmp_err = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_err, - MMC_RXICMP_ERR_PKTS_L); - mmc->mmc_rx_icmp_err_h = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_h, - MMC_RXICMP_ERR_PKTS_H); - mmc->mmc_rx_ipv4_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd_octets, - MMC_RXIPV4_GD_OCTETS_L); - mmc->mmc_rx_ipv4_gd_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_gd_octets_h, - MMC_RXIPV4_GD_OCTETS_H); - mmc->mmc_rx_ipv4_hderr_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr_octets, - MMC_RXIPV4_HDRERR_OCTETS_L); - mmc->mmc_rx_ipv4_hderr_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_hderr_octets_h, - MMC_RXIPV4_HDRERR_OCTETS_H); - mmc->mmc_rx_ipv4_nopay_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay_octets, - MMC_RXIPV4_NOPAY_OCTETS_L); - mmc->mmc_rx_ipv4_nopay_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_nopay_octets_h, - MMC_RXIPV4_NOPAY_OCTETS_H); - mmc->mmc_rx_ipv4_frag_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag_octets, - MMC_RXIPV4_FRAG_OCTETS_L); - mmc->mmc_rx_ipv4_frag_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_frag_octets_h, - MMC_RXIPV4_FRAG_OCTETS_H); - mmc->mmc_rx_ipv4_udsbl_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl_octets, - MMC_RXIPV4_UDP_CHKSM_DIS_OCT_L); - mmc->mmc_rx_ipv4_udsbl_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv4_udsbl_octets_h, - MMC_RXIPV4_UDP_CHKSM_DIS_OCT_H); - mmc->mmc_rx_udp_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets, - MMC_RXUDP_GD_OCTETS_L); - mmc->mmc_rx_udp_gd_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_udp_gd_octets_h, - MMC_RXUDP_GD_OCTETS_H); - mmc->mmc_rx_ipv6_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets, - MMC_RXIPV6_GD_OCTETS_L); - mmc->mmc_rx_ipv6_gd_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_gd_octets_h, - MMC_RXIPV6_GD_OCTETS_H); - mmc->mmc_rx_ipv6_hderr_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets, - MMC_RXIPV6_HDRERR_OCTETS_L); - mmc->mmc_rx_ipv6_hderr_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_hderr_octets_h, - MMC_RXIPV6_HDRERR_OCTETS_H); - mmc->mmc_rx_ipv6_nopay_octets = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets, - MMC_RXIPV6_NOPAY_OCTETS_L); - mmc->mmc_rx_ipv6_nopay_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_ipv6_nopay_octets_h, - MMC_RXIPV6_NOPAY_OCTETS_H); - mmc->mmc_rx_udp_err_octets = - update_mmc_val(osi_core, mmc->mmc_rx_udp_err_octets, - MMC_RXUDP_ERR_OCTETS_L); - mmc->mmc_rx_udp_err_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_udp_err_octets_h, - MMC_RXUDP_ERR_OCTETS_H); - mmc->mmc_rx_tcp_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd_octets, - MMC_RXTCP_GD_OCTETS_L); - mmc->mmc_rx_tcp_gd_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_gd_octets_h, - MMC_RXTCP_GD_OCTETS_H); - mmc->mmc_rx_tcp_err_octets = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_err_octets, - MMC_RXTCP_ERR_OCTETS_L); - mmc->mmc_rx_tcp_err_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_tcp_err_octets_h, - MMC_RXTCP_ERR_OCTETS_H); - mmc->mmc_rx_icmp_gd_octets = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd_octets, - MMC_RXICMP_GD_OCTETS_L); - mmc->mmc_rx_icmp_gd_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_gd_octets_h, - MMC_RXICMP_GD_OCTETS_H); - mmc->mmc_rx_icmp_err_octets = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets, - MMC_RXICMP_ERR_OCTETS_L); - mmc->mmc_rx_icmp_err_octets_h = - update_mmc_val(osi_core, mmc->mmc_rx_icmp_err_octets_h, - MMC_RXICMP_ERR_OCTETS_H); - mmc->mmc_tx_fpe_frag_cnt = - update_mmc_val(osi_core, mmc->mmc_tx_fpe_frag_cnt, - MMC_TX_FPE_FRAG_COUNTER); - mmc->mmc_tx_fpe_hold_req_cnt = - update_mmc_val(osi_core, mmc->mmc_tx_fpe_hold_req_cnt, - MMC_TX_HOLD_REQ_COUNTER); - mmc->mmc_rx_packet_reass_err_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_reass_err_cnt, - MMC_RX_PKT_ASSEMBLY_ERR_CNTR); - mmc->mmc_rx_packet_smd_err_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_smd_err_cnt, - MMC_RX_PKT_SMD_ERR_CNTR); - mmc->mmc_rx_packet_asm_ok_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_packet_asm_ok_cnt, - MMC_RX_PKT_ASSEMBLY_OK_CNTR); - mmc->mmc_rx_fpe_fragment_cnt = - update_mmc_val(osi_core, mmc->mmc_rx_fpe_fragment_cnt, - MMC_RX_FPE_FRAG_CNTR); -} diff --git a/osi/core/mgbe_mmc.h b/osi/core/mgbe_mmc.h deleted file mode 100644 index 957577d..0000000 --- a/osi/core/mgbe_mmc.h +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2020, 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 MGBE_MMC_H_ -#define MGBE_MMC_H_ - -/** - * @addtogroup MGBE-MMC MMC HW register offsets - * - * @brief MMC HW register offsets - * @{ - */ -#define MMC_TXOCTETCOUNT_GB_L 0x00814 -#define MMC_TXOCTETCOUNT_GB_H 0x00818 -#define MMC_TXPACKETCOUNT_GB_L 0x0081C -#define MMC_TXPACKETCOUNT_GB_H 0x00820 -#define MMC_TXBROADCASTPACKETS_G_L 0x00824 -#define MMC_TXBROADCASTPACKETS_G_H 0x00828 -#define MMC_TXMULTICASTPACKETS_G_L 0x0082C -#define MMC_TXMULTICASTPACKETS_G_H 0x00830 -#define MMC_TX64OCTETS_GB_L 0x00834 -#define MMC_TX64OCTETS_GB_H 0x00838 -#define MMC_TX65TO127OCTETS_GB_L 0x0083C -#define MMC_TX65TO127OCTETS_GB_H 0x00840 -#define MMC_TX128TO255OCTETS_GB_L 0x00844 -#define MMC_TX128TO255OCTETS_GB_H 0x00848 -#define MMC_TX256TO511OCTETS_GB_L 0x0084C -#define MMC_TX256TO511OCTETS_GB_H 0x00850 -#define MMC_TX512TO1023OCTETS_GB_L 0x00854 -#define MMC_TX512TO1023OCTETS_GB_H 0x00858 -#define MMC_TX1024TOMAXOCTETS_GB_L 0x0085C -#define MMC_TX1024TOMAXOCTETS_GB_H 0x00860 -#define MMC_TXUNICASTPACKETS_GB_L 0x00864 -#define MMC_TXUNICASTPACKETS_GB_H 0x00868 -#define MMC_TXMULTICASTPACKETS_GB_L 0x0086C -#define MMC_TXMULTICASTPACKETS_GB_H 0x00870 -#define MMC_TXBROADCASTPACKETS_GB_L 0x00874 -#define MMC_TXBROADCASTPACKETS_GB_H 0x00878 -#define MMC_TXUNDERFLOWERROR_L 0x0087C -#define MMC_TXUNDERFLOWERROR_H 0x00880 -#define MMC_TXOCTETCOUNT_G_L 0x00884 -#define MMC_TXOCTETCOUNT_G_H 0x00888 -#define MMC_TXPACKETSCOUNT_G_L 0x0088C -#define MMC_TXPACKETSCOUNT_G_H 0x00890 -#define MMC_TXPAUSEPACKETS_L 0x00894 -#define MMC_TXPAUSEPACKETS_H 0x00898 -#define MMC_TXVLANPACKETS_G_L 0x0089C -#define MMC_TXVLANPACKETS_G_H 0x008A0 -#define MMC_TXLPIUSECCNTR 0x008A4 -#define MMC_TXLPITRANCNTR 0x008A8 -#define MMC_PRIO_INT_STATUS 0x008CC -#define MMC_TX_PER_PRIO_STATUS 0x008D0 -#define MMC_TX_PER_PRIO_PKT_GB 0x008D4 -#define MMC_TX_PER_PRIO_PFC_PKT_GB 0x008D8 -#define MMC_TX_PER_PRIO_GPFC_PKT_GB 0x008DC -#define MMC_TX_PER_PRIO_OCTET_GB_L 0x008E0 -#define MMC_TX_PER_PRIO_OCTET_GB_H 0x008E4 - -#define MMC_RXPACKETCOUNT_GB_L 0x00900 -#define MMC_RXPACKETCOUNT_GB_H 0x00904 -#define MMC_RXOCTETCOUNT_GB_L 0x00908 -#define MMC_RXOCTETCOUNT_GB_H 0x0090C -#define MMC_RXOCTETCOUNT_G_L 0x00910 -#define MMC_RXOCTETCOUNT_G_H 0x00914 -#define MMC_RXBROADCASTPACKETS_G_L 0x00918 -#define MMC_RXBROADCASTPACKETS_G_H 0x0091C -#define MMC_RXMULTICASTPACKETS_G_L 0x00920 -#define MMC_RXMULTICASTPACKETS_G_H 0x00924 -#define MMC_RXCRCERROR_L 0x00928 -#define MMC_RXCRCERROR_H 0x0092C -#define MMC_RXRUNTERROR 0x00930 -#define MMC_RXJABBERERROR 0x00934 -#define MMC_RXUNDERSIZE_G 0x00938 -#define MMC_RXOVERSIZE_G 0x0093C -#define MMC_RX64OCTETS_GB_L 0x00940 -#define MMC_RX64OCTETS_GB_H 0x00944 -#define MMC_RX65TO127OCTETS_GB_L 0x00948 -#define MMC_RX65TO127OCTETS_GB_H 0x0094C -#define MMC_RX128TO255OCTETS_GB_L 0x00950 -#define MMC_RX128TO255OCTETS_GB_H 0x00954 -#define MMC_RX256TO511OCTETS_GB_L 0x00958 -#define MMC_RX256TO511OCTETS_GB_H 0x0095C -#define MMC_RX512TO1023OCTETS_GB_L 0x00960 -#define MMC_RX512TO1023OCTETS_GB_H 0x00964 -#define MMC_RX1024TOMAXOCTETS_GB_L 0x00968 -#define MMC_RX1024TOMAXOCTETS_GB_H 0x0096C -#define MMC_RXUNICASTPACKETS_G_L 0x00970 -#define MMC_RXUNICASTPACKETS_G_H 0x00974 -#define MMC_RXLENGTHERROR_L 0x00978 -#define MMC_RXLENGTHERROR_H 0x0097C -#define MMC_RXOUTOFRANGETYPE_L 0x00980 -#define MMC_RXOUTOFRANGETYPE_H 0x00984 -#define MMC_RXPAUSEPACKETS_L 0x00988 -#define MMC_RXPAUSEPACKETS_H 0x0098C -#define MMC_RXFIFOOVERFLOW_L 0x00990 -#define MMC_RXFIFOOVERFLOW_H 0x00994 -#define MMC_RXVLANPACKETS_GB_L 0x00998 -#define MMC_RXVLANPACKETS_GB_H 0x0099C -#define MMC_RXWATCHDOGERROR 0x009A0 -#define MMC_RXLPIUSECCNTR 0x009A4 -#define MMC_RXLPITRANCNTR 0x009A8 -#define MMC_RX_DISCARD_PKTS_GB_L 0x009AC -#define MMC_RX_DISCARD_PKTS_GB_H 0x009B0 -#define MMC_RX_DISCARD_OCTET_GB_L 0x009B4 -#define MMC_RX_DISCARD_OCTET_GB_H 0x009B8 -#define MMC_RXALIGNMENTERROR 0x009BC -#define MMC_RX_PER_PRIO_STATUS 0x009D0 -#define MMC_RX_PER_PRIO_PKT_GB 0x009D4 -#define MMC_RX_PER_PRIO_PKT_B 0x009D8 -#define MMC_RX_PER_PRIO_PFC_PKT_GB 0x009DC -#define MMC_RX_PER_PRIO_OCTET_GB_L 0x009E0 -#define MMC_RX_PER_PRIO_OCTET_GB_H 0x009E4 -#define MMC_RX_PER_PRIO_DISCARD_GB 0x009E8 -#define MMC_FPE_TX_INT 0x00A00 -#define MMC_FPE_TX_INT_MASK 0x00A04 -#define MMC_TX_FPE_FRAG_COUNTER 0x00A08 -#define MMC_TX_HOLD_REQ_COUNTER 0x00A0C -#define MMC_FPE_RX_INT 0x00A20 -#define MMC_FPE_RX_INT_MASK 0x00A24 -#define MMC_RX_PKT_ASSEMBLY_ERR_CNTR 0x00A28 -#define MMC_RX_PKT_SMD_ERR_CNTR 0x00A2C -#define MMC_RX_PKT_ASSEMBLY_OK_CNTR 0x00A30 -#define MMC_RX_FPE_FRAG_CNTR 0x00A34 -#define MMC_TXSINGLECOL_G 0x00A40 -#define MMC_TXMULTICOL_G 0x00A44 -#define MMC_TXDEFERRED 0x00A48 -#define MMC_TXLATECOL 0x00A4C -#define MMC_TXEXESSCOL 0x00A50 -#define MMC_TXCARRIERERROR 0x00A54 -#define MMC_TXEXECESS_DEFERRED 0x00A58 -#define MMC_IPC_RX_INT_MASK 0x00A5C -#define MMC_IPC_RX_INT 0x00A60 -#define MMC_RXIPV4_GD_PKTS_L 0x00A64 -#define MMC_RXIPV4_GD_PKTS_H 0x00A68 -#define MMC_RXIPV4_HDRERR_PKTS_L 0x00A6C -#define MMC_RXIPV4_HDRERR_PKTS_H 0x00A70 -#define MMC_RXIPV4_NOPAY_PKTS_L 0x00A74 -#define MMC_RXIPV4_NOPAY_PKTS_H 0x00A78 -#define MMC_RXIPV4_FRAG_PKTS_L 0x00A7C -#define MMC_RXIPV4_FRAG_PKTS_H 0x00A80 -#define MMC_RXIPV4_UBSBL_PKTS_L 0x00A84 -#define MMC_RXIPV4_UBSBL_PKTS_H 0x00A88 -#define MMC_RXIPV6_GD_PKTS_L 0x00A8C -#define MMC_RXIPV6_GD_PKTS_H 0x00A90 -#define MMC_RXIPV6_HDRERR_PKTS_L 0x00A94 -#define MMC_RXIPV6_HDRERR_PKTS_H 0x00A98 -#define MMC_RXIPV6_NOPAY_PKTS_L 0x00A9C -#define MMC_RXIPV6_NOPAY_PKTS_H 0x00AA0 -#define MMC_RXUDP_GD_PKTS_L 0x00AA4 -#define MMC_RXUDP_GD_PKTS_H 0x00AA8 -#define MMC_RXUDP_ERR_PKTS_L 0x00AAC -#define MMC_RXUDP_ERR_PKTS_H 0x00AB0 -#define MMC_RXTCP_GD_PKTS_L 0x00AB4 -#define MMC_RXTCP_GD_PKTS_H 0x00AB8 -#define MMC_RXTCP_ERR_PKTS_L 0x00ABC -#define MMC_RXTCP_ERR_PKTS_H 0x00AC0 -#define MMC_RXICMP_GD_PKTS_L 0x00AC4 -#define MMC_RXICMP_GD_PKTS_H 0x00AC8 -#define MMC_RXICMP_ERR_PKTS_L 0x00ACC -#define MMC_RXICMP_ERR_PKTS_H 0x00AD0 -#define MMC_RXIPV4_GD_OCTETS_L 0x00AD4 -#define MMC_RXIPV4_GD_OCTETS_H 0x00AD8 -#define MMC_RXIPV4_HDRERR_OCTETS_L 0x00ADC -#define MMC_RXIPV4_HDRERR_OCTETS_H 0x00AE0 -#define MMC_RXIPV4_NOPAY_OCTETS_L 0x00AE4 -#define MMC_RXIPV4_NOPAY_OCTETS_H 0x00AE8 -#define MMC_RXIPV4_FRAG_OCTETS_L 0x00AEC -#define MMC_RXIPV4_FRAG_OCTETS_H 0x00AF0 -#define MMC_RXIPV4_UDP_CHKSM_DIS_OCT_L 0x00AF4 -#define MMC_RXIPV4_UDP_CHKSM_DIS_OCT_H 0x00AF8 -#define MMC_RXIPV6_GD_OCTETS_L 0x00AFC -#define MMC_RXIPV6_GD_OCTETS_H 0x00B00 -#define MMC_RXIPV6_HDRERR_OCTETS_L 0x00B04 -#define MMC_RXIPV6_HDRERR_OCTETS_H 0x00B08 -#define MMC_RXIPV6_NOPAY_OCTETS_L 0x00B0C -#define MMC_RXIPV6_NOPAY_OCTETS_H 0x00B10 -#define MMC_RXUDP_GD_OCTETS_L 0x00B14 -#define MMC_RXUDP_GD_OCTETS_H 0x00B18 -#define MMC_RXUDP_ERR_OCTETS_L 0x00B1C -#define MMC_RXUDP_ERR_OCTETS_H 0x00B20 -#define MMC_RXTCP_GD_OCTETS_L 0x00B24 -#define MMC_RXTCP_GD_OCTETS_H 0x00B28 -#define MMC_RXTCP_ERR_OCTETS_L 0x00B2C -#define MMC_RXTCP_ERR_OCTETS_H 0x00B30 -#define MMC_RXICMP_GD_OCTETS_L 0x00B34 -#define MMC_RXICMP_GD_OCTETS_H 0x00B38 -#define MMC_RXICMP_ERR_OCTETS_L 0x00B3C -#define MMC_RXICMP_ERR_OCTETS_H 0x00B40 -/** @} */ - -/** - * @brief mgbe_read_mmc - To read MMC registers and ether_mmc_counter structure - * variable - * - * Algorithm: Pass register offset and old value to helper function and - * update structure. - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - */ -void mgbe_read_mmc(struct osi_core_priv_data *osi_core); - -/** - * @brief mgbe_reset_mmc - To reset MMC registers and ether_mmc_counter - * structure variable - * - * @param[in] osi_core: OSI core private data structure. - * - * @note - * 1) MAC should be init and started. see osi_start_mac() - * 2) osi_core->osd should be populated - */ -void mgbe_reset_mmc(struct osi_core_priv_data *osi_core); -#endif diff --git a/osi/core/osi_core.c b/osi/core/osi_core.c deleted file mode 100644 index 75c9e72..0000000 --- a/osi/core/osi_core.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 "core_local.h" -#include "../osi/common/common.h" - -#ifdef HSI_SUPPORT -/** - * @brief hsi_err_code - Arry of error code and reporter ID to be use by - * each Ethernet controller instance - * a condition is met or a timeout occurs - * Below is the data: - * uncorrectable_error_code, correctable_error_code, reporter ID - * hsi_err_code[0] to hsi_err_code[3] for MGBE instance - * hsi_err_code[4] is for EQOS - */ -nveu32_t hsi_err_code[][3] = { - {0x2A00, 0x2E08, 0x8019}, - {0x2A01, 0x2E09, 0x801A}, - {0x2A02, 0x2E0A, 0x801B}, - {0x2A03, 0x2E0B, 0x801C}, - {0x28AD, 0x2DE6, 0x8009}, -}; -#endif - -/** - * @brief g_core - Static core local data array - */ -static struct core_local g_core[MAX_CORE_INSTANCES]; - -/** - * @brief if_ops - Static core interface operations for virtual/non-virtual - * case - */ -static struct if_core_ops if_ops[MAX_INTERFACE_OPS]; - -/** - * @brief Function to validate function pointers. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t validate_if_func_ptrs(struct osi_core_priv_data *const osi_core, - struct if_core_ops *if_ops_p) -{ - nveu32_t i = 0; - void *temp_ops = (void *)if_ops_p; -#if __SIZEOF_POINTER__ == 8 - nveu64_t *l_ops = (nveu64_t *)temp_ops; -#elif __SIZEOF_POINTER__ == 4 - nveu32_t *l_ops = (nveu32_t *)temp_ops; -#else - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Undefined architecture\n", 0ULL); - return -1; -#endif - - for (i = 0; i < (sizeof(*if_ops_p) / (nveu64_t)__SIZEOF_POINTER__); - i++) { - if (*l_ops == 0U) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "failed at index : ", i); - return -1; - } - - l_ops++; - } - - return 0; -} - -/** - * @brief Function to validate input arguments of API. - * - * @param[in] osi_core: OSI Core private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t validate_if_args(struct osi_core_priv_data *const osi_core, - struct core_local *l_core) -{ - if ((osi_core == OSI_NULL) || (l_core->if_init_done == OSI_DISABLE) || - (l_core->magic_num != (nveu64_t)osi_core)) { - return -1; - } - - return 0; -} - -struct osi_core_priv_data *osi_get_core(void) -{ - nveu32_t i; - - for (i = 0U; i < MAX_CORE_INSTANCES; i++) { - if (g_core[i].if_init_done == OSI_ENABLE) { - continue; - } - - break; - } - - if (i == MAX_CORE_INSTANCES) { - return OSI_NULL; - } - - g_core[i].magic_num = (nveu64_t)&g_core[i].osi_core; - - g_core[i].tx_ts_head.prev = &g_core[i].tx_ts_head; - g_core[i].tx_ts_head.next = &g_core[i].tx_ts_head; - g_core[i].pps_freq = OSI_DISABLE; - - return &g_core[i].osi_core; -} - -struct osi_core_priv_data *get_role_pointer(nveu32_t role) -{ - nveu32_t i; - - if ((role != OSI_PTP_M2M_PRIMARY) && - (role != OSI_PTP_M2M_SECONDARY)) { - return OSI_NULL; - } - - /* Current approch to give pointer for 1st role */ - for (i = 0U; i < MAX_CORE_INSTANCES; i++) { - if ((g_core[i].if_init_done == OSI_ENABLE) && - (g_core[i].ether_m2m_role == role)) { - return &g_core[i].osi_core; - } - } - - return OSI_NULL; -} - -nve32_t osi_init_core_ops(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret = -1; - - if (osi_core == OSI_NULL) { - return -1; - } - - if (osi_core->use_virtualization > OSI_ENABLE) { - return ret; - } - - if ((l_core->magic_num != (nveu64_t)osi_core) || - (l_core->if_init_done == OSI_ENABLE)) { - return -1; - } - - l_core->if_ops_p = &if_ops[osi_core->use_virtualization]; - - if (osi_core->use_virtualization == OSI_DISABLE) { - hw_interface_init_core_ops(l_core->if_ops_p); - } else { - ivc_interface_init_core_ops(l_core->if_ops_p); - } - - if (validate_if_func_ptrs(osi_core, l_core->if_ops_p) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Interface function validation failed\n", 0ULL); - return -1; - } - - ret = l_core->if_ops_p->if_init_core_ops(osi_core); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "if_init_core_ops failed\n", 0ULL); - return ret; - } - l_core->ts_lock = OSI_DISABLE; - l_core->ether_m2m_role = osi_core->m2m_role; - l_core->serv.count = SERVO_STATS_0; - l_core->serv.drift = 0; - l_core->serv.last_ppb = 0; - osi_lock_init(&l_core->serv.m2m_lock); -#ifdef MACSEC_SUPPORT - osi_lock_init(&osi_core->macsec_fpe_lock); -#endif /* MACSEC_SUPPORT */ - l_core->hw_init_successful = OSI_DISABLE; - l_core->m2m_tsync = OSI_DISABLE; - l_core->if_init_done = OSI_ENABLE; - if ((osi_core->m2m_role == OSI_PTP_M2M_PRIMARY) || - (osi_core->m2m_role == OSI_PTP_M2M_SECONDARY)) { - l_core->m2m_tsync = OSI_ENABLE; - } else { - l_core->m2m_tsync = OSI_DISABLE; - } - - if (osi_core->pps_frq <= OSI_ENABLE) { - l_core->pps_freq = osi_core->pps_frq; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "invalid pps_frq\n", (nveu64_t)osi_core->pps_frq); - ret = -1; - } - - return ret; -} - -nve32_t osi_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg, - const nveu16_t phydata) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_if_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->if_ops_p->if_write_phy_reg(osi_core, phyaddr, phyreg, - phydata); -} - -nve32_t osi_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_if_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->if_ops_p->if_read_phy_reg(osi_core, phyaddr, phyreg); -} - -nve32_t osi_hw_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_if_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->if_ops_p->if_core_init(osi_core, tx_fifo_size, - rx_fifo_size); -} - -nve32_t osi_hw_core_deinit(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_if_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->if_ops_p->if_core_deinit(osi_core); -} - -nve32_t osi_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret = -1; - - if (validate_if_args(osi_core, l_core) < 0) { - return ret; - } - - if (data == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Invalid argument\n", 0ULL); - return ret; - } - - return l_core->if_ops_p->if_handle_ioctl(osi_core, data); -} diff --git a/osi/core/osi_hal.c b/osi/core/osi_hal.c deleted file mode 100644 index 0407070..0000000 --- a/osi/core/osi_hal.c +++ /dev/null @@ -1,2096 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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 "core_local.h" -#include "../osi/common/common.h" -#include "vlan_filter.h" -#include "frp.h" -#ifdef OSI_DEBUG -#include "debug.h" -#endif /* OSI_DEBUG */ - -/** - * @brief g_ops - Static core operations array. - */ -static struct core_ops g_ops[MAX_MAC_IP_TYPES]; - -/** - * @brief Function to validate input arguments of API. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] l_core: OSI local core data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t validate_args(struct osi_core_priv_data *const osi_core, - struct core_local *l_core) -{ - if ((osi_core == OSI_NULL) || (osi_core->base == OSI_NULL) || - (l_core->init_done == OSI_DISABLE) || - (l_core->magic_num != (nveu64_t)osi_core)) { - return -1; - } - - return 0; -} - -/** - * @brief Function to validate function pointers. - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] ops_p: OSI Core operations structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t validate_func_ptrs(struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p) -{ - nveu32_t i = 0; - void *temp_ops = (void *)ops_p; -#if __SIZEOF_POINTER__ == 8 - nveu64_t *l_ops = (nveu64_t *)temp_ops; -#elif __SIZEOF_POINTER__ == 4 - nveu32_t *l_ops = (nveu32_t *)temp_ops; -#else - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Undefined architecture\n", 0ULL); - return -1; -#endif - - for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { - if (*l_ops == 0U) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "core: fn ptr validation failed at\n", - (nveu64_t)i); - return -1; - } - - l_ops++; - } - - return 0; -} - -nve32_t osi_hal_write_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg, - const nveu16_t phydata) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->write_phy_reg(osi_core, phyaddr, phyreg, phydata); -} - -nve32_t osi_hal_read_phy_reg(struct osi_core_priv_data *const osi_core, - const nveu32_t phyaddr, const nveu32_t phyreg) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->read_phy_reg(osi_core, phyaddr, phyreg); -} - -static nve32_t osi_hal_init_core_ops(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - typedef void (*init_ops_arr)(struct core_ops *); - typedef void *(*safety_init)(void); - - init_ops_arr i_ops[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { - { eqos_init_core_ops, OSI_NULL }, - { mgbe_init_core_ops, OSI_NULL } - }; - - safety_init s_init[MAX_MAC_IP_TYPES][MAX_MAC_IP_TYPES] = { - { eqos_get_core_safety_config, ivc_get_core_safety_config }, - { OSI_NULL, OSI_NULL } - }; - - if (osi_core == OSI_NULL) { - return -1; - } - - if ((l_core->magic_num != (nveu64_t)osi_core) || - (l_core->init_done == OSI_ENABLE)) { - return -1; - } - - if ((osi_core->osd_ops.ops_log == OSI_NULL) || - (osi_core->osd_ops.udelay == OSI_NULL) || - (osi_core->osd_ops.msleep == OSI_NULL) || -#ifdef OSI_DEBUG - (osi_core->osd_ops.printf == OSI_NULL) || -#endif /* OSI_DEBUG */ - (osi_core->osd_ops.usleep_range == OSI_NULL)) { - return -1; - } - - if (osi_core->mac > OSI_MAC_HW_MGBE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC HW type\n", 0ULL); - return -1; - } - - if (osi_core->use_virtualization > OSI_ENABLE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid use_virtualization value\n", 0ULL); - return -1; - } - - if (i_ops[osi_core->mac][osi_core->use_virtualization] != OSI_NULL) { - i_ops[osi_core->mac][osi_core->use_virtualization](&g_ops[osi_core->mac]); - } - - if (s_init[osi_core->mac][osi_core->use_virtualization] != OSI_NULL) { - osi_core->safety_config = - s_init[osi_core->mac][osi_core->use_virtualization](); - } - - if (validate_func_ptrs(osi_core, &g_ops[osi_core->mac]) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "core: function ptrs validation failed\n", 0ULL); - return -1; - } - - l_core->ops_p = &g_ops[osi_core->mac]; - l_core->init_done = OSI_ENABLE; - - return 0; -} - -nve32_t osi_poll_for_mac_reset_complete( - struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->poll_for_swr(osi_core); -} - -/** - * @brief init_vlan_filters - Helper function to init all VLAN SW information. - * - * Algorithm: Initialize VLAN filtering information. - * - * @param[in] osi_core: OSI Core private data structure. - */ -static inline void init_vlan_filters(struct osi_core_priv_data *const osi_core) -{ - unsigned int i = 0U; - - for (i = 0; i < VLAN_NUM_VID; i++) { - osi_core->vid[i] = VLAN_ID_INVALID; - } - - osi_core->vf_bitmap = 0U; - osi_core->vlan_filter_cnt = 0U; -} - -nve32_t osi_hal_hw_core_init(struct osi_core_priv_data *const osi_core, - nveu32_t tx_fifo_size, nveu32_t rx_fifo_size) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - init_vlan_filters(osi_core); - - /* Init FRP */ - init_frp(osi_core); - - ret = l_core->ops_p->core_init(osi_core, tx_fifo_size, rx_fifo_size); - - if (ret == 0) { - l_core->hw_init_successful = OSI_ENABLE; - } - - return ret; -} - -nve32_t osi_hal_hw_core_deinit(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->hw_init_successful = OSI_DISABLE; - l_core->ops_p->core_deinit(osi_core); - - /* FIXME: Should be fixed */ - //l_core->init_done = OSI_DISABLE; - //l_core->magic_num = 0; - - return 0; -} - -nve32_t osi_start_mac(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->start_mac(osi_core); - - return 0; -} - -nve32_t osi_stop_mac(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->stop_mac(osi_core); - - return 0; -} - -nve32_t osi_common_isr(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->handle_common_intr(osi_core); - - return 0; -} - -nve32_t osi_set_mode(struct osi_core_priv_data *const osi_core, - const nve32_t mode) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->set_mode(osi_core, mode); -} - -nve32_t osi_set_speed(struct osi_core_priv_data *const osi_core, - const nve32_t speed) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->set_speed(osi_core, speed); -} - -nve32_t osi_pad_calibrate(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->pad_calibrate(osi_core); -} - -nve32_t osi_config_fw_err_pkts(struct osi_core_priv_data *const osi_core, - const nveu32_t qinx, const nveu32_t fw_err) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - /* Configure Forwarding of Error packets */ - return l_core->ops_p->config_fw_err_pkts(osi_core, qinx, fw_err); -} - -static nve32_t conf_ptp_offload(struct osi_core_priv_data *const osi_core, - struct osi_pto_config *const pto_config) -{ - struct core_local *l_core = (struct core_local *)osi_core; - int ret = -1; - - /* Validate input arguments */ - if (pto_config == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "pto_config is NULL\n", 0ULL); - return ret; - } - - if (pto_config->mc_uc != OSI_ENABLE && - pto_config->mc_uc != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid mc_uc flag value\n", - (nveul64_t)pto_config->mc_uc); - return ret; - } - - if (pto_config->en_dis != OSI_ENABLE && - pto_config->en_dis != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid enable flag value\n", - (nveul64_t)pto_config->en_dis); - return ret; - } - - if (pto_config->snap_type != OSI_PTP_SNAP_ORDINARY && - pto_config->snap_type != OSI_PTP_SNAP_TRANSPORT && - pto_config->snap_type != OSI_PTP_SNAP_P2P) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid SNAP type value\n", - (nveul64_t)pto_config->snap_type); - return ret; - } - - if (pto_config->master != OSI_ENABLE && - pto_config->master != OSI_DISABLE) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid master flag value\n", - (nveul64_t)pto_config->master); - return ret; - } - - if (pto_config->domain_num >= OSI_PTP_MAX_DOMAIN) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid ptp domain\n", - (nveul64_t)pto_config->domain_num); - return ret; - } - - if (pto_config->portid >= OSI_PTP_MAX_PORTID) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "invalid ptp port ID\n", - (nveul64_t)pto_config->portid); - return ret; - } - - ret = l_core->ops_p->config_ptp_offload(osi_core, pto_config); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Fail to configure PTO\n", - (nveul64_t)pto_config->en_dis); - return ret; - } - - /* Configure PTP */ - ret = osi_ptp_configuration(osi_core, pto_config->en_dis); - if (ret < 0) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Fail to configure PTP\n", - (nveul64_t)pto_config->en_dis); - return ret; - } - - return ret; -} - -nve32_t osi_l2_filter(struct osi_core_priv_data *const osi_core, - const struct osi_filter *filter) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret; - - if ((validate_args(osi_core, l_core) < 0) || (filter == OSI_NULL)) { - return -1; - } - - if (filter == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: filter is NULL\n", 0ULL); - return -1; - } - - ret = l_core->ops_p->config_mac_pkt_filter_reg(osi_core, filter); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "failed to configure MAC packet filter register\n", - 0ULL); - return ret; - } - - if (((filter->oper_mode & OSI_OPER_ADDR_UPDATE) != OSI_NONE) || - ((filter->oper_mode & OSI_OPER_ADDR_DEL) != OSI_NONE)) { - ret = -1; - - if ((filter->dma_routing == OSI_ENABLE) && - (osi_core->dcs_en != OSI_ENABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "DCS requested. Conflicts with DT config\n", - 0ULL); - return ret; - } - - ret = l_core->ops_p->update_mac_addr_low_high_reg(osi_core, - filter); - } - - return ret; -} - -/** - * @brief helper_l4_filter helper function for l4 filtering - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] l_filter: filter structure - * @param[in] type: filter type l3 or l4 - * @param[in] dma_routing_enable: dma routing enable (1) or disable (0) - * @param[in] dma_chan: dma channel - * - * @pre MAC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t helper_l4_filter( - struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_l3_l4_filter l_filter, - nveu32_t type, - nveu32_t dma_routing_enable, - nveu32_t dma_chan) -{ - nve32_t ret = 0; - - ret = ops_p->config_l4_filters(osi_core, - l_filter.filter_no, - l_filter.filter_enb_dis, - type, - l_filter.src_dst_addr_match, - l_filter.perfect_inverse_match, - dma_routing_enable, - dma_chan); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "failed to configure L4 filters\n", 0ULL); - return ret; - } - - return ops_p->update_l4_port_no(osi_core, - l_filter.filter_no, - l_filter.port_no, - l_filter.src_dst_addr_match); -} - -/** - * @brief helper_l3_filter helper function for l3 filtering - * - * @param[in] osi_core: OSI Core private data structure. - * @param[in] l_filter: filter structure - * @param[in] type: filter type l3 or l4 - * @param[in] dma_routing_enable: dma routing enable (1) or disable (0) - * @param[in] dma_chan: dma channel - * - * @pre MAC needs to be out of reset and proper clock configured. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t helper_l3_filter( - struct osi_core_priv_data *const osi_core, - struct core_ops *ops_p, - struct osi_l3_l4_filter l_filter, - nveu32_t type, - nveu32_t dma_routing_enable, - nveu32_t dma_chan) -{ - nve32_t ret = 0; - - ret = ops_p->config_l3_filters(osi_core, - l_filter.filter_no, - l_filter.filter_enb_dis, - type, - l_filter.src_dst_addr_match, - l_filter.perfect_inverse_match, - dma_routing_enable, - dma_chan); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "failed to configure L3 filters\n", 0ULL); - return ret; - } - - if (type == OSI_IP6_FILTER) { - ret = ops_p->update_ip6_addr(osi_core, l_filter.filter_no, - l_filter.ip6_addr); - } else if (type == OSI_IP4_FILTER) { - ret = ops_p->update_ip4_addr(osi_core, l_filter.filter_no, - l_filter.ip4_addr, - l_filter.src_dst_addr_match); - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid L3 filter type\n", 0ULL); - return -1; - } - - return ret; -} - -nve32_t osi_l3l4_filter(struct osi_core_priv_data *const osi_core, - const struct osi_l3_l4_filter l_filter, - const nveu32_t type, const nveu32_t dma_routing_enable, - const nveu32_t dma_chan, const nveu32_t is_l4_filter) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret = -1; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if ((dma_routing_enable == OSI_ENABLE) && - (osi_core->dcs_en != OSI_ENABLE)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "dma routing enabled but dcs disabled in DT\n", - 0ULL); - return ret; - } - - if (is_l4_filter == OSI_ENABLE) { - ret = helper_l4_filter(osi_core, l_core->ops_p, l_filter, type, - dma_routing_enable, dma_chan); - } else { - ret = helper_l3_filter(osi_core, l_core->ops_p, l_filter, type, - dma_routing_enable, dma_chan); - } - - if (ret < 0) { - OSI_CORE_INFO(osi_core->osd, OSI_LOG_ARG_INVALID, - "L3/L4 helper function failed\n", 0ULL); - return ret; - } - - if (osi_core->l3l4_filter_bitmask != OSI_DISABLE) { - ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, - OSI_ENABLE); - } else { - ret = l_core->ops_p->config_l3_l4_filter_enable(osi_core, - OSI_DISABLE); - } - - return ret; -} - -nve32_t osi_config_rxcsum_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->config_rxcsum_offload(osi_core, enable); -} - -nve32_t osi_set_systime_to_mac(struct osi_core_priv_data *const osi_core, - const nveu32_t sec, const nveu32_t nsec) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - return l_core->ops_p->set_systime_to_mac(osi_core, sec, nsec); -} - -/** - * @brief div_u64 - Calls a function which returns quotient - * - * @param[in] dividend: Dividend - * @param[in] divisor: Divisor - * - * @pre MAC IP should be out of reset and need to be initialized as the - * requirements. - * - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * @returns Quotient - */ -static inline nveu64_t div_u64(nveu64_t dividend, - nveu64_t divisor) -{ - nveu64_t remain; - - return div_u64_rem(dividend, divisor, &remain); -} - -nve32_t osi_adjust_freq(struct osi_core_priv_data *const osi_core, nve32_t ppb) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - nveu64_t adj; - nveu64_t temp; - nveu32_t diff = 0; - nveu32_t addend; - nveu32_t neg_adj = 0; - nve32_t ret = -1; - nve32_t ppb1 = ppb; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - addend = osi_core->default_addend; - if (ppb1 < 0) { - neg_adj = 1U; - ppb1 = -ppb1; - adj = (nveu64_t)addend * (nveu32_t)ppb1; - } else { - adj = (nveu64_t)addend * (nveu32_t)ppb1; - } - - /* - * div_u64 will divide the "adj" by "1000000000ULL" - * and return the quotient. - */ - temp = div_u64(adj, OSI_NSEC_PER_SEC); - if (temp < UINT_MAX) { - diff = (nveu32_t)temp; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, "temp > UINT_MAX\n", - 0ULL); - return ret; - } - - if (neg_adj == 0U) { - if (addend <= (UINT_MAX - diff)) { - addend = (addend + diff); - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "addend > UINT_MAX\n", 0ULL); - return ret; - } - } else { - if (addend > diff) { - addend = addend - diff; - } else if (addend < diff) { - addend = diff - addend; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "addend = diff\n", 0ULL); - } - } - - return l_core->ops_p->config_addend(osi_core, addend); -} - -nve32_t osi_adjust_time(struct osi_core_priv_data *const osi_core, - nvel64_t nsec_delta) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nveu32_t neg_adj = 0; - nveu32_t sec = 0, nsec = 0; - nveu64_t quotient; - nveu64_t reminder = 0; - nveu64_t udelta = 0; - nve32_t ret = -1; - nvel64_t nsec_delta1 = nsec_delta; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (nsec_delta1 < 0) { - neg_adj = 1; - nsec_delta1 = -nsec_delta1; - udelta = (nveul64_t)nsec_delta1; - } else { - udelta = (nveul64_t)nsec_delta1; - } - - quotient = div_u64_rem(udelta, OSI_NSEC_PER_SEC, &reminder); - if (quotient <= UINT_MAX) { - sec = (nveu32_t)quotient; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "quotient > UINT_MAX\n", 0ULL); - return ret; - } - - if (reminder <= UINT_MAX) { - nsec = (nveu32_t)reminder; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "reminder > UINT_MAX\n", 0ULL); - return ret; - } - - return l_core->ops_p->adjust_mactime(osi_core, sec, nsec, neg_adj, - osi_core->ptp_config.one_nsec_accuracy); -} - -nve32_t osi_ptp_configuration(struct osi_core_priv_data *const osi_core, - const nveu32_t enable) -{ - struct core_local *l_core = (struct core_local *)osi_core; - nve32_t ret = 0; - nveu64_t temp = 0, temp1 = 0, temp2 = 0; - nveu64_t ssinc = 0; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (enable == OSI_DISABLE) { - /* disable hw time stamping */ - /* Program MAC_Timestamp_Control Register */ - l_core->ops_p->config_tscr(osi_core, OSI_DISABLE); - /* Disable PTP RX Queue routing */ - ret = l_core->ops_p->config_ptp_rxq(osi_core, - osi_core->ptp_config.ptp_rx_queue, - OSI_DISABLE); - } else { - /* Program MAC_Timestamp_Control Register */ - l_core->ops_p->config_tscr(osi_core, - osi_core->ptp_config.ptp_filter); - - if (osi_core->pre_si == OSI_ENABLE) { - if (osi_core->mac == OSI_MAC_HW_MGBE) { - /* FIXME: Pass it from OSD */ - osi_core->ptp_config.ptp_clock = 78125000U; - osi_core->ptp_config.ptp_ref_clk_rate = - 78125000U; - } else { - /* FIXME: Pass it from OSD */ - osi_core->ptp_config.ptp_clock = 312500000U; - osi_core->ptp_config.ptp_ref_clk_rate = - 312500000U; - } - } - /* Program Sub Second Increment Register */ - l_core->ops_p->config_ssir(osi_core, - osi_core->ptp_config.ptp_clock); - - /* formula for calculating addend value is - * TSAR = (2^32 * 1000) / (ptp_ref_clk_rate in MHz * SSINC) - * 2^x * y == (y << x), hence - * 2^32 * 1000 == (1000 << 32) - * so addend = (2^32 * 1000)/(ptp_ref_clk_rate in MHZ * SSINC); - */ - if ((osi_core->pre_si == OSI_ENABLE) && - ((osi_core->mac == OSI_MAC_HW_MGBE) || - (osi_core->mac_ver <= OSI_EQOS_MAC_4_10))) { - ssinc = OSI_PTP_SSINC_16; - } else { - ssinc = OSI_PTP_SSINC_4; - if (osi_core->mac_ver == OSI_EQOS_MAC_5_30) { - ssinc = OSI_PTP_SSINC_6; - } - } - - temp = ((nveu64_t)1000 << 32); - temp = (nveu64_t)temp * 1000000U; - - temp1 = div_u64(temp, - (nveu64_t)osi_core->ptp_config.ptp_ref_clk_rate); - - temp2 = div_u64(temp1, (nveu64_t)ssinc); - - if (temp2 < UINT_MAX) { - osi_core->default_addend = (nveu32_t)temp2; - } else { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "core: temp2 >= UINT_MAX\n", 0ULL); - return -1; - } - - /* Program addend value */ - ret = l_core->ops_p->config_addend(osi_core, - osi_core->default_addend); - - /* Set current time */ - if (ret == 0) { - ret = l_core->ops_p->set_systime_to_mac(osi_core, - osi_core->ptp_config.sec, - osi_core->ptp_config.nsec); - if (ret == 0) { - /* Enable PTP RX Queue routing */ - ret = l_core->ops_p->config_ptp_rxq(osi_core, - osi_core->ptp_config.ptp_rx_queue, - OSI_ENABLE); - } - } - } - - return ret; -} - -/** - * @brief rxq_route_config - Enable PTP RX packets routing - * - * Algorithm: Program PTP RX queue index - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] rx_route: Pointer to the osi_rxq_route structure, which - * contains RXQ routing parameters. - * - * @note MAC should be init and started. see osi_start_mac() - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t rxq_route_config(struct osi_core_priv_data *const osi_core, - const struct osi_rxq_route *rxq_route) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (rxq_route->route_type != OSI_RXQ_ROUTE_PTP) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "Invalid route_type\n", - rxq_route->route_type); - return -1; - } - - return l_core->ops_p->config_ptp_rxq(osi_core, - rxq_route->idx, - rxq_route->enable); -} - -nve32_t osi_read_mmc(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - l_core->ops_p->read_mmc(osi_core); - - return 0; -} - -nve32_t osi_get_mac_version(struct osi_core_priv_data *const osi_core, - nveu32_t *mac_ver) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (mac_ver == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "mac_ver is NULL\n", 0ULL); - return -1; - } - - *mac_ver = ((l_core->ops_p->read_reg(osi_core, (nve32_t)MAC_VERSION)) & - MAC_VERSION_SNVER_MASK); - - if (validate_mac_ver_update_chans(*mac_ver, &l_core->max_chans) == 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)*mac_ver) - return -1; - } - - return 0; -} - -#ifndef OSI_STRIPPED_LIB -/** - * @brief validate_core_regs - Read-validate HW registers for func safety. - * - * @note - * Algorithm: - * - Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. - * - * @param[in] osi_core: OSI core private data structure. - * - * @pre - * - MAC has to be out of reset. - * - osi_hal_hw_core_init has to be called. Internally this would initialize - * the safety_config (see osi_core_priv_data) based on MAC version and - * which specific registers needs to be validated periodically. - * - Invoke this call if (osi_core_priv_data->safety_config != OSI_NULL) - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t validate_core_regs(struct osi_core_priv_data *const osi_core) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (osi_core->safety_config == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Safety config is NULL\n", 0ULL); - return -1; - } - - return l_core->ops_p->validate_regs(osi_core); -} - -/** - * @brief vlan_id_update - invoke osi call to update VLAN ID - * - * @note - * Algorithm: - * - return 16 bit VLAN ID - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] vid: VLAN ID - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t vlan_id_update(struct osi_core_priv_data *const osi_core, - const nveu32_t vid) -{ - struct core_local *l_core = (struct core_local *)osi_core; - unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = vid & VLAN_VID_MASK; - - if ((osi_core->mac_ver == OSI_EQOS_MAC_4_10) || - (osi_core->mac_ver == OSI_EQOS_MAC_5_00)) { - /* No VLAN ID filtering */ - return 0; - } - - if (((action != OSI_VLAN_ACTION_ADD) && - (action != OSI_VLAN_ACTION_DEL)) || - (vlan_id >= VLAN_NUM_VID)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Invalid action/vlan_id\n", 0ULL); - /* Unsupported action */ - return -1; - } - - return update_vlan_id(osi_core, l_core->ops_p, vid); -} - -/** - * @brief conf_eee - Configure EEE LPI in MAC. - * - * @note - * Algorithm: - * - This routine invokes configuration of EEE LPI in the MAC. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] tx_lpi_enabled: Enable (1)/disable (0) tx lpi - * @param[in] tx_lpi_timer: Tx LPI entry timer in usecs upto - * OSI_MAX_TX_LPI_TIMER (in steps of 8usec) - * - * @pre - * - MAC and PHY should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t conf_eee(struct osi_core_priv_data *const osi_core, - nveu32_t tx_lpi_enabled, nveu32_t tx_lpi_timer) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if ((tx_lpi_timer >= OSI_MAX_TX_LPI_TIMER) || - (tx_lpi_timer <= OSI_MIN_TX_LPI_TIMER) || - ((tx_lpi_timer % OSI_MIN_TX_LPI_TIMER) != OSI_NONE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid Tx LPI timer value\n", - (nveul64_t)tx_lpi_timer); - return -1; - } - - l_core->ops_p->configure_eee(osi_core, tx_lpi_enabled, tx_lpi_timer); - - return 0; -} - -/** - * @brief configure_frp - Configure the FRP offload entry in the - * Instruction Table. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] cmd: FRP command data structure. - * - * @pre - * - MAC and PHY should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static int configure_frp(struct osi_core_priv_data *const osi_core, - struct osi_core_frp_cmd *const cmd) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (cmd == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid argment\n", OSI_NONE); - return -1; - } - - /* Check for supported MAC version */ - if ((osi_core->mac == OSI_MAC_HW_EQOS) && - (osi_core->mac_ver < OSI_EQOS_MAC_5_10)) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_HW_FAIL, - "MAC doesn't support FRP\n", OSI_NONE); - return -1; - } - - return setup_frp(osi_core, l_core->ops_p, cmd); -} - -/** - * @brief config_arp_offload - Configure ARP offload in MAC. - * - * @note - * Algorithm: - * - Invokes EQOS config ARP offload routine. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] flags: Enable/disable flag. - * @param[in] ip_addr: Char array representation of IP address - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - Valid 4 byte IP address as argument ip_addr - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t conf_arp_offload(struct osi_core_priv_data *const osi_core, - const nveu32_t flags, - const nveu8_t *ip_addr) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (ip_addr == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: ip_addr is NULL\n", 0ULL); - return -1; - } - - if ((flags != OSI_ENABLE) && (flags != OSI_DISABLE)) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid ARP offload enable/disable flag\n", 0ULL); - return -1; - } - - return l_core->ops_p->config_arp_offload(osi_core, flags, ip_addr); -} - -/** - * @brief conf_mac_loopback - Configure MAC loopback - * - * @note - * Algorithm: - * - Configure the MAC to support the loopback. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] lb_mode: Enable or disable MAC loopback - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t conf_mac_loopback(struct osi_core_priv_data *const osi_core, - const nveu32_t lb_mode) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - /* don't allow only if loopback mode is other than 0 or 1 */ - if (lb_mode != OSI_ENABLE && lb_mode != OSI_DISABLE) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid loopback mode\n", 0ULL); - return -1; - } - - return l_core->ops_p->config_mac_loopback(osi_core, lb_mode); -} -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief config_est - Read Setting for GCL from input and update - * registers. - * - * Algorithm: - * - Write TER, LLR and EST control register - * - Update GCL to sw own GCL (MTL_EST_Status bit SWOL will tell which is - * owned by SW) and store which GCL is in use currently in sw. - * - TODO set DBGB and DBGM for debugging - * - EST_data and GCRR to 1, update entry sno in ADDR and put data at - * est_gcl_data enable GCL MTL_EST_SSWL and wait for self clear or use - * SWLC in MTL_EST_Status. Please note new GCL will be pushed for each entry. - * - Configure btr. Update btr based on current time (current time - * should be updated based on PTP by this time) - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] est: Configuration osi_est_config structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t config_est(struct osi_core_priv_data *osi_core, - struct osi_est_config *est) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (est == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "EST data is NULL", 0ULL); - return -1; - } - - if ((osi_core->flow_ctrl & OSI_FLOW_CTRL_TX) == - OSI_FLOW_CTRL_TX) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "TX Flow control enabled, please disable it", - 0ULL); - return -1; - } - - return l_core->ops_p->hw_config_est(osi_core, est); -} - -/** - * @brief config_fep - Read Setting for preemption and express for TC - * and update registers. - * - * Algorithm: - * - Check for TC enable and TC has masked for setting to preemptable. - * - Update FPE control status register - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] fpe: Configuration osi_fpe_config structure. - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - * @note - * Traceability Details: - * - * @note - * Classification: - * - Interrupt: No - * - Signal handler: No - * - Thread safe: No - * - Required Privileges: None - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t config_fpe(struct osi_core_priv_data *osi_core, - struct osi_fpe_config *fpe) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (fpe == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "FPE data is NULL", 0ULL); - return -1; - } - - return l_core->ops_p->hw_config_fpe(osi_core, fpe); -} - -/** - * @brief Free stale timestamps for channel - * - * Algorithm: - * - Check for if any timestamp for input channel id - * - if yes, reset node to 0x0 for reuse. - * - * @param[in] osi_core: OSI core private data structure. - * @param[in] chan: 1 for DMA channel 0, 2 for dma channel 1,... - * 0 is used for onestep. - */ -static inline void free_tx_ts(struct osi_core_priv_data *osi_core, - nveu32_t chan) -{ - struct core_local *l_core = (struct core_local *)osi_core; - struct osi_core_tx_ts *head = &l_core->tx_ts_head; - struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; - nveu32_t count = 0U; - - while ((temp != head) && (count < MAX_TX_TS_CNT)) { - if (((temp->pkt_id >> CHAN_START_POSITION) & chan) == chan) { - temp->next->prev = temp->prev; - temp->prev->next = temp->next; - /* reset in_use for temp node from the link */ - temp->in_use = OSI_DISABLE; - } - count++; - temp = temp->next; - } -} - -/** - * @brief Parses internal ts structure array and update time stamp if packet - * id matches. - * Algorithm: - * - Check for if any timestamp with packet ID in list and valid - * - update sec and nsec in timestamp structure - * - reset node to reuse for next call - * - * @param[in] osi_core: OSI core private data structure. - * @param[in,out] ts: osi core ts structure, pkt_id is input and time is output. - * - * @retval 0 on success - * @retval -1 any other failure. - */ -static inline nve32_t get_tx_ts(struct osi_core_priv_data *osi_core, - struct osi_core_tx_ts *ts) -{ - struct core_local *l_core = (struct core_local *)osi_core; - struct osi_core_tx_ts *temp = l_core->tx_ts_head.next; - struct osi_core_tx_ts *head = &l_core->tx_ts_head; - nve32_t ret = -1; - nveu32_t count = 0U; - - if (__sync_fetch_and_add(&l_core->ts_lock, 1) == 1U) { - /* mask return as initial value is returned always */ - (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); - osi_core->xstats.ts_lock_del_fail = - osi_update_stats_counter( - osi_core->xstats.ts_lock_del_fail, 1U); - goto done; - } - - while ((temp != head) && (count < MAX_TX_TS_CNT)) { - if ((temp->pkt_id == ts->pkt_id) && - (temp->in_use != OSI_NONE)) { - ts->sec = temp->sec; - ts->nsec = temp->nsec; - /* remove temp node from the link */ - temp->next->prev = temp->prev; - temp->prev->next = temp->next; - /* Clear in_use fields */ - temp->in_use = OSI_DISABLE; - ret = 0; - break; - } - count++; - temp = temp->next; - } - - /* mask return as initial value is returned always */ - (void)__sync_fetch_and_sub(&l_core->ts_lock, 1); -done: - return ret; -} - -#if DRIFT_CAL -/** - * @brief read time counters from HW register - * - * Algorithm: - * - read HW time counters and take care of roll-over - * - * @param[in] addr: base address - * @param[in] mac: IP type - * @param[out] sec: sec counter - * @param[out] nsec: nsec counter - */ -static void read_sec_ns(void *addr, nveu32_t mac, - nveu32_t *sec, - nveu32_t *nsec) -{ - nveu32_t ns1, ns2; - nveu32_t time_reg_offset[][2] = {{EQOS_SEC_OFFSET, EQOS_NSEC_OFFSET}, - {MGBE_SEC_OFFSET, MGBE_NSEC_OFFSET}}; - - ns1 = osi_readl((nveu8_t *)addr + time_reg_offset[mac][1]); - ns1 = (ns1 & ETHER_NSEC_MASK); - - *sec = osi_readl((nveu8_t *)addr + time_reg_offset[mac][0]); - - ns2 = osi_readl((nveu8_t *)addr + time_reg_offset[mac][1]); - ns2 = (ns2 & ETHER_NSEC_MASK); - - /* if ns1 is greater than ns2, it means nsec counter rollover - * happened. In that case read the updated sec counter again - */ - if (ns1 >= ns2) { - *sec = osi_readl((nveu8_t *)addr + time_reg_offset[mac][0]); - *nsec = ns2; - } else { - *nsec = ns1; - } -} - -/** - * @brief calculate time drift between primary and secondary - * interface. - * Algorithm: - * - Get drift using last difference = 0 and - * current differance as MGBE time - EQOS time - * drift = current differance with which EQOS should - * update. - * - * @param[in] sec: primary interface sec counter - * @param[in] nsec: primary interface nsec counter - * @param[in] secondary_sec: Secondary interface sec counter - * @param[in] secondary_nsec: Secondary interface nsec counter - * - * @retval calculated drift value - */ -static inline nvel64_t dirft_calculation(nveu32_t sec, nveu32_t nsec, - nveu32_t secondary_sec, - nveu32_t secondary_nsec) -{ - nvel64_t val = 0LL; - - val = (nvel64_t)sec - (nvel64_t)secondary_sec; - val = (nvel64_t)(val * 1000000000LL); - val += (nvel64_t)nsec - (nvel64_t)secondary_nsec; - - return val; -} - -/** - * @brief calculate frequency adjustment between primary and secondary - * controller. - * Algorithm: - * - Convert Offset between primary and secondary interface to - * frequency adjustment value. - * - * @param[in] sec_osi_core: secondary interface osi core pointer - * @param[in] offset: offset btween primary and secondary interface - * @param[in] secondary_time: Secondary interface time in ns - * - * @retval calculated frequency adjustment value in ppb - */ -static inline nve32_t freq_offset_calculate(struct osi_core_priv_data *sec_osi_core, - nvel64_t offset, nvel64_t secondary_time) -{ - struct core_ptp_servo *s; - struct core_local *secondary_osi_lcore = (struct core_local *)sec_osi_core; - nvel64_t ki_term, ppb = 0; - nvel64_t cofficient; - - s = &secondary_osi_lcore->serv; - ppb = s->last_ppb; - - /* if drift is too big in positive / negative don't take any action, - * it should be corrected with adjust time - * threshold value 1 sec - */ - if (offset >= 1000000000 || offset <= -1000000000) { - s->count = SERVO_STATS_0; /* JUMP */ - return (nve32_t) s->last_ppb; - } - - switch (s->count) { - case SERVO_STATS_0: - s->offset[0] = offset; - s->local[0] = secondary_time; - s->count = SERVO_STATS_1; - break; - - case SERVO_STATS_1: - s->offset[1] = offset; - s->local[1] = secondary_time; - - /* Make sure the first sample is older than the second. */ - if (s->local[0] >= s->local[1]) { - s->count = SERVO_STATS_0; - break; - } - - /* Adjust drift by the measured frequency offset. */ - cofficient = (1000000000LL - s->drift) / (s->local[1] - s->local[0]); - s->drift += cofficient * s->offset[1]; - - /* update this with constant */ - if (s->drift < -MAX_FREQ) { - s->drift = -MAX_FREQ; - } else if (s->drift > MAX_FREQ) { - s->drift = MAX_FREQ; - } - - ppb = s->drift; - s->count = SERVO_STATS_2; - s->offset[0] = s->offset[1]; - s->local[0] = s->local[1]; - break; - - case SERVO_STATS_2: - s->offset[1] = offset; - s->local[1] = secondary_time; - cofficient = (1000000000LL) / (s->local[1] - s->local[0]); - /* calculate ppb */ - ki_term = (s->const_i * cofficient * offset * WEIGHT_BY_10) / (100);//weight; - ppb = (s->const_p * cofficient * offset * WEIGHT_BY_10) / (100) + s->drift + - ki_term; - - /* FIXME tune cofficients */ - if (ppb < -MAX_FREQ) { - ppb = -MAX_FREQ; - } else if (ppb > MAX_FREQ) { - ppb = MAX_FREQ; - } else { - s->drift += ki_term; - } - s->offset[0] = s->offset[1]; - s->local[0] = s->local[1]; - break; - default: - break; - } - - s->last_ppb = ppb; - - return (nve32_t)ppb; -} -#endif - -nve32_t osi_hal_handle_ioctl(struct osi_core_priv_data *osi_core, - struct osi_ioctl *data) -{ - struct core_local *l_core = (struct core_local *)osi_core; - struct core_ops *ops_p; - nve32_t ret = -1; -#if DRIFT_CAL - struct osi_core_priv_data *sec_osi_core; - struct core_local *secondary_osi_lcore; - struct core_ops *secondary_ops_p; - nvel64_t drift_value = 0x0; - nveu32_t sec = 0x0; - nveu32_t nsec = 0x0; - nveu32_t secondary_sec = 0x0; - nveu32_t secondary_nsec = 0x0; - nve32_t freq_adj_value = 0x0; - nvel64_t secondary_time; -#endif - - if (validate_args(osi_core, l_core) < 0) { - return ret; - } - - ops_p = l_core->ops_p; - - if (data == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Invalid argument\n", 0ULL); - return -1; - } - - switch (data->cmd) { -#ifndef OSI_STRIPPED_LIB - case OSI_CMD_RESTORE_REGISTER: - ret = ops_p->restore_registers(osi_core); - break; - - case OSI_CMD_L3L4_FILTER: - ret = osi_l3l4_filter(osi_core, data->l3l4_filter, - data->arg1_u32, data->arg2_u32, - data->arg3_u32, data->arg4_u32); - break; - - case OSI_CMD_MDC_CONFIG: - ops_p->set_mdc_clk_rate(osi_core, data->arg5_u64); - ret = 0; - break; - - case OSI_CMD_VALIDATE_CORE_REG: - ret = validate_core_regs(osi_core); - break; - - case OSI_CMD_RESET_MMC: - ops_p->reset_mmc(osi_core); - ret = 0; - break; - - case OSI_CMD_SAVE_REGISTER: - ret = ops_p->save_registers(osi_core); - break; - - case OSI_CMD_MAC_LB: - ret = conf_mac_loopback(osi_core, data->arg1_u32); - break; - - case OSI_CMD_FLOW_CTRL: - ret = ops_p->config_flow_control(osi_core, data->arg1_u32); - break; - - case OSI_CMD_GET_AVB: - ret = ops_p->get_avb_algorithm(osi_core, &data->avb); - break; - - case OSI_CMD_SET_AVB: - ret = ops_p->set_avb_algorithm(osi_core, &data->avb); - break; - - case OSI_CMD_CONFIG_RX_CRC_CHECK: - ret = ops_p->config_rx_crc_check(osi_core, data->arg1_u32); - break; - - case OSI_CMD_UPDATE_VLAN_ID: - ret = vlan_id_update(osi_core, data->arg1_u32); - break; - - case OSI_CMD_CONFIG_TXSTATUS: - ret = ops_p->config_tx_status(osi_core, data->arg1_u32); - break; - - case OSI_CMD_CONFIG_FW_ERR: - ret = ops_p->config_fw_err_pkts(osi_core, data->arg1_u32, - data->arg2_u32); - break; - - case OSI_CMD_ARP_OFFLOAD: - ret = conf_arp_offload(osi_core, data->arg1_u32, - data->arg7_u8_p); - break; - - case OSI_CMD_VLAN_FILTER: - ret = ops_p->config_vlan_filtering(osi_core, - data->vlan_filter.filter_enb_dis, - data->vlan_filter.perfect_hash, - data->vlan_filter.perfect_inverse_match); - break; - - case OSI_CMD_CONFIG_EEE: - ret = conf_eee(osi_core, data->arg1_u32, data->arg2_u32); - break; - -#endif /* !OSI_STRIPPED_LIB */ - case OSI_CMD_POLL_FOR_MAC_RST: - ret = ops_p->poll_for_swr(osi_core); - break; - - case OSI_CMD_START_MAC: - ops_p->start_mac(osi_core); - ret = 0; - break; - - case OSI_CMD_STOP_MAC: - ops_p->stop_mac(osi_core); - ret = 0; - break; - - case OSI_CMD_COMMON_ISR: - ops_p->handle_common_intr(osi_core); - ret = 0; - break; - - case OSI_CMD_PAD_CALIBRATION: - ret = ops_p->pad_calibrate(osi_core); - break; - - case OSI_CMD_READ_MMC: - ops_p->read_mmc(osi_core); - ret = 0; - break; - - case OSI_CMD_GET_MAC_VER: - ret = osi_get_mac_version(osi_core, &data->arg1_u32); - break; - - case OSI_CMD_SET_MODE: - ret = ops_p->set_mode(osi_core, data->arg6_32); - break; - - case OSI_CMD_SET_SPEED: - ret = ops_p->set_speed(osi_core, data->arg6_32); - break; - - case OSI_CMD_L2_FILTER: - ret = osi_l2_filter(osi_core, &data->l2_filter); - break; - - case OSI_CMD_RXCSUM_OFFLOAD: - ret = ops_p->config_rxcsum_offload(osi_core, data->arg1_u32); - break; - - case OSI_CMD_ADJ_FREQ: - ret = osi_adjust_freq(osi_core, data->arg6_32); -#if DRIFT_CAL - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: adjust freq failed\n", 0ULL); - break; - } - - if ((l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) && - (l_core->m2m_tsync != OSI_ENABLE)) { - break; - } - - sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; - if ((validate_args(sec_osi_core, secondary_osi_lcore) < 0) || - (secondary_osi_lcore->hw_init_successful != OSI_ENABLE) || - (secondary_osi_lcore->m2m_tsync != OSI_ENABLE)) { - break; - } - - if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { - drift_value = 0x0; - osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - read_sec_ns(sec_osi_core->base, - sec_osi_core->mac, &secondary_sec, &secondary_nsec); - read_sec_ns(osi_core->base, - osi_core->mac, &sec, &nsec); - osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - - drift_value = dirft_calculation(sec, nsec, secondary_sec, secondary_nsec); - secondary_time = (secondary_sec * 1000000000LL) + secondary_nsec; - secondary_osi_lcore->serv.const_i = I_COMPONENT_BY_10; - secondary_osi_lcore->serv.const_p = P_COMPONENT_BY_10; - freq_adj_value = freq_offset_calculate(sec_osi_core, - drift_value, - secondary_time); - if (secondary_osi_lcore->serv.count == SERVO_STATS_0) { - /* call adjust time as JUMP happened */ - ret = osi_adjust_time(sec_osi_core, - drift_value); - } else { - ret = osi_adjust_freq(sec_osi_core, - freq_adj_value); - } - } - - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: adjust_freq for sec_controller failed\n", - 0ULL); - ret = 0; - } -#endif - break; - - case OSI_CMD_ADJ_TIME: - ret = osi_adjust_time(osi_core, data->arg8_64); -#if DRIFT_CAL - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: adjust_time failed\n", 0ULL); - break; - } - - if ((l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) && - (l_core->m2m_tsync != OSI_ENABLE)) { - break; - } - - sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; - if ((validate_args(sec_osi_core, secondary_osi_lcore) < 0) || - (secondary_osi_lcore->hw_init_successful != OSI_ENABLE) || - (secondary_osi_lcore->m2m_tsync != OSI_ENABLE)) { - break; - } - - if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { - drift_value = 0x0; - osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - read_sec_ns(sec_osi_core->base, - sec_osi_core->mac, &secondary_sec, &secondary_nsec); - read_sec_ns(osi_core->base, - osi_core->mac, &sec, &nsec); - osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - drift_value = dirft_calculation(sec, nsec, - secondary_sec, - secondary_nsec); - ret = osi_adjust_time(sec_osi_core, drift_value); - if (ret == 0) { - secondary_osi_lcore->serv.count = SERVO_STATS_0; - secondary_osi_lcore->serv.drift = 0; - secondary_osi_lcore->serv.last_ppb = 0; - } - } - - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: adjust_time for sec_controller failed\n", - 0ULL); - ret = 0; - } -#endif - break; - - case OSI_CMD_CONFIG_PTP: - ret = osi_ptp_configuration(osi_core, data->arg1_u32); -#if DRIFT_CAL - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: configure_ptp failed\n", 0ULL); - break; - } - - if ((l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) && - (l_core->m2m_tsync != OSI_ENABLE)) { - break; - } - - sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; - if ((validate_args(sec_osi_core, secondary_osi_lcore) < 0) || - (secondary_osi_lcore->hw_init_successful != OSI_ENABLE) || - (secondary_osi_lcore->m2m_tsync != OSI_ENABLE)) { - break; - } - - if ((l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) && - (data->arg1_u32 == OSI_ENABLE)) { - secondary_osi_lcore->serv.count = SERVO_STATS_0; - secondary_osi_lcore->serv.drift = 0; - secondary_osi_lcore->serv.last_ppb = 0; - } -#endif - break; - - case OSI_CMD_GET_HW_FEAT: - ret = ops_p->get_hw_features(osi_core, &data->hw_feat); - break; - - case OSI_CMD_SET_SYSTOHW_TIME: - ret = ops_p->set_systime_to_mac(osi_core, data->arg1_u32, - data->arg2_u32); -#if DRIFT_CAL - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: set systohw time failed\n", 0ULL); - break; - } - - if ((l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) && - (l_core->m2m_tsync != OSI_ENABLE)) { - break; - } - - sec_osi_core = get_role_pointer(OSI_PTP_M2M_SECONDARY); - secondary_osi_lcore = (struct core_local *)sec_osi_core; - if ((validate_args(sec_osi_core, secondary_osi_lcore) < 0) || - (secondary_osi_lcore->hw_init_successful != OSI_ENABLE) || - (secondary_osi_lcore->m2m_tsync != OSI_ENABLE)) { - break; - } - - if (l_core->ether_m2m_role == OSI_PTP_M2M_PRIMARY) { - drift_value = 0x0; - osi_lock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - read_sec_ns(osi_core->base, - osi_core->mac, &sec, &nsec); - osi_unlock_irq_enabled(&secondary_osi_lcore->serv.m2m_lock); - secondary_ops_p = secondary_osi_lcore->ops_p; - ret = secondary_ops_p->set_systime_to_mac(sec_osi_core, sec, - nsec); - if (ret == 0) { - secondary_osi_lcore->serv.count = SERVO_STATS_0; - secondary_osi_lcore->serv.drift = 0; - secondary_osi_lcore->serv.last_ppb = 0; - } - } - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: set_time for sec_controller failed\n", - 0ULL); - ret = 0; - } -#endif - break; - case OSI_CMD_CONFIG_PTP_OFFLOAD: - ret = conf_ptp_offload(osi_core, &data->pto_config); - break; - - case OSI_CMD_PTP_RXQ_ROUTE: - ret = rxq_route_config(osi_core, &data->rxq_route); - break; - - case OSI_CMD_CONFIG_FRP: - ret = configure_frp(osi_core, &data->frp_cmd); - break; - - case OSI_CMD_CONFIG_RSS: - ret = ops_p->config_rss(osi_core); - break; - - case OSI_CMD_CONFIG_EST: - ret = config_est(osi_core, &data->est); - break; - - case OSI_CMD_CONFIG_FPE: - ret = config_fpe(osi_core, &data->fpe); - break; - - case OSI_CMD_READ_REG: - ret = (nve32_t) ops_p->read_reg(osi_core, (nve32_t) data->arg1_u32); - break; - - case OSI_CMD_WRITE_REG: - ret = (nve32_t) ops_p->write_reg(osi_core, (nveu32_t) data->arg1_u32, - (nve32_t) data->arg2_u32); - break; -#ifdef MACSEC_SUPPORT - case OSI_CMD_READ_MACSEC_REG: - ret = (nve32_t) ops_p->read_macsec_reg(osi_core, (nve32_t) data->arg1_u32); - break; - - case OSI_CMD_WRITE_MACSEC_REG: - ret = (nve32_t) ops_p->write_macsec_reg(osi_core, (nveu32_t) data->arg1_u32, - (nve32_t) data->arg2_u32); - break; -#endif /* MACSEC_SUPPORT */ - case OSI_CMD_GET_TX_TS: - ret = get_tx_ts(osi_core, &data->tx_ts); - break; - - case OSI_CMD_FREE_TS: - free_tx_ts(osi_core, data->arg1_u32); - ret = 0; - break; - - case OSI_CMD_MAC_MTU: - ret = 0; - break; - -#ifdef OSI_DEBUG - case OSI_CMD_REG_DUMP: - core_reg_dump(osi_core); - ret = 0; - break; - case OSI_CMD_STRUCTS_DUMP: - core_structs_dump(osi_core); - ret = 0; - break; -#endif /* OSI_DEBUG */ - case OSI_CMD_CAP_TSC_PTP: - ret = ops_p->ptp_tsc_capture(osi_core, &data->ptp_tsc); - break; - - case OSI_CMD_CONF_M2M_TS: - if (data->arg1_u32 <= OSI_ENABLE) { - l_core->m2m_tsync = data->arg1_u32; - ret = 0; - } - break; -#ifdef HSI_SUPPORT - case OSI_CMD_HSI_CONFIGURE: - ret = ops_p->core_hsi_configure(osi_core, data->arg1_u32); - break; -#endif - default: - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Incorrect command\n", - (nveul64_t)data->cmd); - break; - } - - return ret; -} - -nve32_t osi_get_hw_features(struct osi_core_priv_data *const osi_core, - struct osi_hw_features *hw_feat) -{ - struct core_local *l_core = (struct core_local *)osi_core; - - if (validate_args(osi_core, l_core) < 0) { - return -1; - } - - if (hw_feat == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "CORE: Invalid hw_feat\n", 0ULL); - return -1; - } - - return l_core->ops_p->get_hw_features(osi_core, hw_feat); -} - -void hw_interface_init_core_ops(struct if_core_ops *if_ops_p) -{ - if_ops_p->if_core_init = osi_hal_hw_core_init; - if_ops_p->if_core_deinit = osi_hal_hw_core_deinit; - if_ops_p->if_write_phy_reg = osi_hal_write_phy_reg; - if_ops_p->if_read_phy_reg = osi_hal_read_phy_reg; - if_ops_p->if_init_core_ops = osi_hal_init_core_ops; - if_ops_p->if_handle_ioctl = osi_hal_handle_ioctl; -} diff --git a/osi/core/vlan_filter.c b/osi/core/vlan_filter.c deleted file mode 100644 index 4f99be2..0000000 --- a/osi/core/vlan_filter.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "../osi/common/common.h" -#include "vlan_filter.h" - -/** - * @brief get_vlan_filter_idx - Get VLAN HW filter index which match vlan_id - * - * Algorithm: From VID flags gets the set bit position and get the value - * from that position and compare with vlan ID passed to this function - * - * @param[in] osi_core: OSI core private data - * @param[in] vlan_id: VLAN ID to be searched in HW filters - * - * @return Index from VID array if match found. - * @return Return VLAN_HW_FILTER_FULL_IDX if not found. - */ -static inline unsigned int get_vlan_filter_idx( - struct osi_core_priv_data *osi_core, - unsigned short vlan_id) -{ - unsigned int vid_idx = VLAN_HW_FILTER_FULL_IDX; - unsigned long bitmap = osi_core->vf_bitmap; - unsigned long temp = 0U; - - while (bitmap != 0U) { - temp = (unsigned long) __builtin_ctzl(bitmap); - - if (osi_core->vid[temp] == vlan_id) { - /* vlan ID match found */ - vid_idx = (unsigned int)temp; - break; - } - - bitmap &= ~OSI_BIT(temp); - } - - return vid_idx; -} - -/** - * @brief allow_all_vid_tags - Program MAC to pass all VID - * - * Algorithm: Enable HASH filtering and program the hash to 0xFFFF - * if all VID's to pass. For not to pass all VID's disable HASH - * filtering and program the HASH as zero. - * - * @param[in] base: MAC base address - * @param[in] pass_all_vids: Flag to pass all VID's or not. - * - * @return 0 on success - */ -static inline int allow_all_vid_tags(unsigned char *base, - unsigned int pass_all_vids) -{ - unsigned int vlan_tag_reg = 0; - unsigned int hash_filter_reg = 0; - - vlan_tag_reg = osi_readl(base + MAC_VLAN_TAG_CTRL); - hash_filter_reg = osi_readl(base + MAC_VLAN_HASH_FILTER); - - if (pass_all_vids == OSI_ENABLE) { - vlan_tag_reg |= MAC_VLAN_TAG_CTRL_VHTM; - hash_filter_reg |= VLAN_HASH_ALLOW_ALL; - } else { - vlan_tag_reg &= ~MAC_VLAN_TAG_CTRL_VHTM; - hash_filter_reg &= (unsigned int) ~VLAN_HASH_ALLOW_ALL; - } - - osi_writel(vlan_tag_reg, base + MAC_VLAN_TAG_CTRL); - osi_writel(hash_filter_reg, base + MAC_VLAN_HASH_FILTER); - - return 0; -} - -/** - * @brief is_vlan_id_enqueued - Checks passed VID already queued or not. - * - * Algorithm: Search VID array from index VLAN_HW_FILTER_FULL_IDX - * to total VID programmed count. If match found return index to VID - * array or return negative value if no match. - * - * @param[in] osi_core: OSI core private data - * @param[in] vlan_id: VLAN ID to be searched in VID array. - * @param[out] idx: Index of the VID array after match - * - * @return 0 on Success. - * @return negative value on failure - */ -static inline int is_vlan_id_enqueued(struct osi_core_priv_data *osi_core, - unsigned short vlan_id, - unsigned int *idx) -{ - unsigned int i = 0; - - if (osi_core->vlan_filter_cnt == VLAN_HW_FILTER_FULL_IDX) { - /* No elements in SW queue to search */ - return -1; - } - - for (i = VLAN_HW_FILTER_FULL_IDX; i <= osi_core->vlan_filter_cnt; i++) { - if (osi_core->vid[i] == vlan_id) { - *idx = i; - /* match found */ - return 0; - } - } - - return -1; -} - -/** - * @brief enqueue_vlan_id - ADD vlan_id to VID array. - * - * Algorithm: Add VLAN ID to VID array at filter_cnt index. - * - * @param[in] osi_core: OSI core private data - * @param[in] vlan_id: VLAN ID to be added to VID array. - * - * @return 0 on success. - * @return negative value on failure. - */ -static inline int enqueue_vlan_id(struct osi_core_priv_data *osi_core, - unsigned short vlan_id) -{ - int ret = 0; - unsigned int idx; - - if (osi_core->vlan_filter_cnt == VLAN_NUM_VID) { - /* Entire SW queue full */ - return -1; - } - - /* Check if requested vlan_id alredy queued */ - ret = is_vlan_id_enqueued(osi_core, vlan_id, &idx); - if (ret == 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "VLAN ID already programmed\n", - 0ULL); - return -1; - } - - osi_core->vid[osi_core->vlan_filter_cnt] = vlan_id; - osi_core->vlan_filter_cnt++; - - return 0; -} - -/** - * @brief poll_for_vlan_filter_reg_rw - Poll for VLAN filter register update - * - * Algorithm: Program VLAN filter registers through indirect address - * mechanism. - * - * @param[in] addr: MAC base address - * - * @return 0 on success. - * @return -1 on failure. - */ -static inline int poll_for_vlan_filter_reg_rw( - struct osi_core_priv_data *osi_core) -{ - unsigned int retry = 10; - unsigned int count; - unsigned int val = 0; - int cond = 1; - - count = 0; - while (cond == 1) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "VLAN filter update timedout\n", 0ULL); - return -1; - } - - count++; - - val = osi_readl((unsigned char *)osi_core->base + - MAC_VLAN_TAG_CTRL); - if ((val & MAC_VLAN_TAG_CTRL_OB) == OSI_NONE) { - /* Set cond to 0 to exit loop */ - cond = 0; - } else { - /* wait for 10 usec for XB clear */ - osi_core->osd_ops.udelay(10U); - } - } - - return 0; -} - -/** - * @brief update_vlan_filters - Update HW filter registers - * - * Algorithm: Program VLAN HW filter registers through indirect - * address mechanism. - * - * @param[in] base: MAC base address. - * @param[in] vid_idx: HW filter index in VLAN filter registers. - * @param[in] val: VLAN ID to be programmed. - * - * @return 0 on success - * @return -1 on failure. - */ -static inline int update_vlan_filters(struct osi_core_priv_data *osi_core, - unsigned int vid_idx, - unsigned int val) -{ - unsigned char *base = (unsigned char *)osi_core->base; - int ret = 0; - - osi_writel(val, base + MAC_VLAN_TAG_DATA); - - val = osi_readl(base + MAC_VLAN_TAG_CTRL); - val &= (unsigned int) ~MAC_VLAN_TAG_CTRL_OFS_MASK; - val |= vid_idx << MAC_VLAN_TAG_CTRL_OFS_SHIFT; - val &= ~MAC_VLAN_TAG_CTRL_CT; - val |= MAC_VLAN_TAG_CTRL_OB; - osi_writel(val, base + MAC_VLAN_TAG_CTRL); - - ret = poll_for_vlan_filter_reg_rw(osi_core); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Failed to update VLAN filters\n", 0ULL); - return -1; - } - - return 0; -} - -/** - * @brief add_vlan_id - Add VLAN ID. - * - * Algorithm: ADD VLAN ID to HW filters and SW VID array. - * - * @param[in] osi_core: OSI core private data. - * @param[in] val: VLAN ID to be programmed. - * - * @return 0 on success - * @return -1 on failure. - */ -static inline int add_vlan_id(struct osi_core_priv_data *osi_core, - struct core_ops *ops_p, - unsigned short vlan_id) -{ - unsigned int vid_idx = 0; - unsigned int val = 0; - int ret = 0; - - /* Check if VLAN ID already programmed */ - vid_idx = get_vlan_filter_idx(osi_core, vlan_id); - if (vid_idx != VLAN_HW_FILTER_FULL_IDX) { - OSI_CORE_ERR(osi_core->osd, OSI_LOG_ARG_INVALID, - "VLAN ID already added\n", - 0ULL); - return -1; - } - - /* Get free index to add the VID */ - vid_idx = (unsigned int) __builtin_ctzl(~osi_core->vf_bitmap); - /* If there is no free filter index add into SW VLAN filter queue to store */ - if (vid_idx == VLAN_HW_FILTER_FULL_IDX) { - /* Add VLAN ID to SW queue */ - ret = enqueue_vlan_id(osi_core, vlan_id); - if (ret < 0) - return ret; - - /* Since VLAN HW filters full - program to allow all packets */ - return allow_all_vid_tags(osi_core->base, OSI_ENABLE); - } - - osi_core->vf_bitmap |= OSI_BIT(vid_idx); - osi_core->vid[vid_idx] = vlan_id; - osi_core->vlan_filter_cnt++; - - if (osi_core->vlan_filter_cnt > 0U) { - ret = ops_p->config_vlan_filtering(osi_core, - OSI_ENABLE, - OSI_DISABLE, - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Failed to enable VLAN filtering\n", 0ULL); - return -1; - } - } - - val = osi_readl((unsigned char *)osi_core->base + MAC_VLAN_TAG_DATA); - val &= (unsigned int) ~VLAN_VID_MASK; - val |= (vlan_id | MAC_VLAN_TAG_DATA_ETV | MAC_VLAN_TAG_DATA_VEN); - - return update_vlan_filters(osi_core, vid_idx, val); -} - -/** - * @brief dequeue_vlan_id - Remove VLAN ID from VID array - * - * Algorithm: Do the left shift of array from index to - * total filter count. Allow all VID tags after removal - * VID if numbers of filter count is 32. - * - * @param[in]: osi_core: OSI core private data. - * @param[in] idx: Index at which VLAN ID to be deleted. - * - * @return 0 on success - * @return -1 on failure. - */ -static inline int dequeue_vlan_id(struct osi_core_priv_data *osi_core, - unsigned int idx) -{ - unsigned int i; - - if (osi_core->vlan_filter_cnt == VLAN_HW_MAX_NRVF) { - return -1; - } - - /* Left shift the array elements by one for the VID order */ - for (i = idx; i <= osi_core->vlan_filter_cnt; i++) { - osi_core->vid[i] = osi_core->vid[i + 1]; - } - - osi_core->vid[i] = VLAN_ID_INVALID; - osi_core->vlan_filter_cnt--; - - if (osi_core->vlan_filter_cnt == VLAN_HW_MAX_NRVF) { - allow_all_vid_tags(osi_core->base, OSI_DISABLE); - } - - return 0; -} - -/** - * @brief dequeue_vid_to_add_filter_reg - Get VID from Array and add to HW - * filters. - * - * Algorithm: Get the VID from index 32 and program in HW filter - * registers. With this first added VID will be programmed in filter registers - * if any VID deleted from HW filter registers. - * - * @param[in]: osi_core: OSI core private data. - * @param[in] idx: Index at which VLAN ID to be deleted. - * - * @return 0 on success - * @return -1 on failure. - */ -static inline int dequeue_vid_to_add_filter_reg( - struct osi_core_priv_data *osi_core, - unsigned int vid_idx) -{ - unsigned int val = 0; - unsigned short vlan_id = 0; - unsigned int i = 0; - int ret = 0; - - vlan_id = osi_core->vid[VLAN_HW_FILTER_FULL_IDX]; - if (vlan_id == VLAN_ID_INVALID) { - return 0; - } - - osi_core->vf_bitmap |= OSI_BIT(vid_idx); - osi_core->vid[vid_idx] = vlan_id; - - val = osi_readl((unsigned char *)osi_core->base + MAC_VLAN_TAG_DATA); - val &= (unsigned int) ~VLAN_VID_MASK; - val |= (vlan_id | MAC_VLAN_TAG_DATA_ETV | MAC_VLAN_TAG_DATA_VEN); - - ret = update_vlan_filters(osi_core, vid_idx, val); - if (ret < 0) { - return -1; - } - - for (i = VLAN_HW_FILTER_FULL_IDX; i <= osi_core->vlan_filter_cnt; i++) { - osi_core->vid[i] = osi_core->vid[i + 1]; - } - - osi_core->vid[i] = VLAN_ID_INVALID; - - return 0; -} - -/** - * @brief del_vlan_id - Delete VLAN ID. - * - * Algorithm: Delete VLAN ID from HW filters or SW VID array. - * - * @param[in] osi_core: OSI core private data. - * @param[in] val: VLAN ID to be deleted - * - * @return 0 on success - * @return -1 on failure. - */ -static inline int del_vlan_id(struct osi_core_priv_data *osi_core, - struct core_ops *ops_p, - unsigned short vlan_id) -{ - unsigned int vid_idx = 0; - unsigned int val = 0; - unsigned int idx; - int ret = 0; - - /* Search for vlan filter index to be deleted */ - vid_idx = get_vlan_filter_idx(osi_core, vlan_id); - if (vid_idx == VLAN_HW_FILTER_FULL_IDX) { - ret = is_vlan_id_enqueued(osi_core, vlan_id, &idx); - if (ret != 0) { - /* VID not found in HW/SW filter list */ - return -1; - } - return dequeue_vlan_id(osi_core, idx); - } - - osi_core->vf_bitmap &= ~OSI_BIT(vid_idx); - osi_core->vid[vid_idx] = VLAN_ID_INVALID; - - ret = update_vlan_filters(osi_core, vid_idx, val); - if (ret < 0) { - return -1; - } - - osi_core->vlan_filter_cnt--; - - if (osi_core->vlan_filter_cnt == 0U) { - ret = ops_p->config_vlan_filtering(osi_core, - OSI_DISABLE, - OSI_DISABLE, - OSI_DISABLE); - if (ret < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Failed to disable VLAN filtering\n", 0ULL); - return -1; - } - } - - if (osi_core->vlan_filter_cnt == VLAN_HW_MAX_NRVF) { - allow_all_vid_tags(osi_core->base, OSI_DISABLE); - } - - /* if SW queue is not empty dequeue from SW queue and update filter */ - return dequeue_vid_to_add_filter_reg(osi_core, vid_idx); -} - -int update_vlan_id(struct osi_core_priv_data *osi_core, - struct core_ops *ops_p, - unsigned int vid) -{ - unsigned int action = vid & VLAN_ACTION_MASK; - unsigned short vlan_id = vid & VLAN_VID_MASK; - - if (action == OSI_VLAN_ACTION_ADD) { - return add_vlan_id(osi_core, ops_p, vlan_id); - } - - return del_vlan_id(osi_core, ops_p, vlan_id); -} diff --git a/osi/core/vlan_filter.h b/osi/core/vlan_filter.h deleted file mode 100644 index d4406ce..0000000 --- a/osi/core/vlan_filter.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2020, 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 VLAN_FILTER_H -#define VLAN_FILTER_H - -#include -#include "core_local.h" - -/** - * @addtogroup MAC-VLAN MAC VLAN configuration registers and bit fields - * - * @brief These are the macros for register offsets and bit fields - * for VLAN configuration. - * @{ - */ -#define MAC_VLAN_TAG_CTRL 0x50 -#define MAC_VLAN_TAG_DATA 0x54 -#define MAC_VLAN_HASH_FILTER 0x58 -#define MAC_VLAN_TAG_CTRL_OFS_MASK 0x7C -#define MAC_VLAN_TAG_CTRL_OFS_SHIFT 2U -#define MAC_VLAN_TAG_CTRL_CT OSI_BIT(1) -#define MAC_VLAN_TAG_CTRL_OB OSI_BIT(0) -#define MAC_VLAN_TAG_CTRL_VHTM OSI_BIT(25) -#define MAC_VLAN_TAG_DATA_ETV OSI_BIT(16) -#define MAC_VLAN_TAG_DATA_VEN OSI_BIT(17) -/** @} */ - -/** - * @addtogroup VLAN filter macros - * - * @brief VLAN filtering releated macros - * @{ - */ -#define VLAN_HW_MAX_NRVF 32U -#define VLAN_HW_FILTER_FULL_IDX VLAN_HW_MAX_NRVF -#define VLAN_VID_MASK 0xFFFF -#define VLAN_ID_INVALID 0xFFFF -#define VLAN_HASH_ALLOW_ALL 0xFFFF -#define VLAN_ACTION_MASK OSI_BIT(31) -/** @} */ - -/** - * @brief update_vlan_id - Add/Delete VLAN ID. - * - * Algorithm: Add/deleted VLAN ID from HW filters or SW VID array. - * - * @param[in] osi_core: OSI core private data. - * @param[in] vid: VLAN ID to be added/deleted - * - * @return 0 on success - * @return -1 on failure. - */ -int update_vlan_id(struct osi_core_priv_data *osi_core, - struct core_ops *ops_p, - unsigned int vid); -#endif /* VLAN_FILTER_H */ diff --git a/osi/core/xpcs.c b/osi/core/xpcs.c deleted file mode 100644 index 6ba0d31..0000000 --- a/osi/core/xpcs.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "xpcs.h" - -/** - * @brief xpcs_poll_for_an_complete - Polling for AN complete. - * - * Algorithm: This routine poll for AN completion status from - * XPCS IP. - * - * @param[in] osi_core: OSI core data structure. - * @param[out] an_status: AN status from XPCS - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline int xpcs_poll_for_an_complete(struct osi_core_priv_data *osi_core, - unsigned int *an_status) -{ - void *xpcs_base = osi_core->xpcs_base; - unsigned int status = 0; - unsigned int retry = 1000; - unsigned int count; - int cond = 1; - int ret = 0; - - /* 14. Poll for AN complete */ - cond = 1; - count = 0; - while (cond == 1) { - if (count > retry) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "XPCS AN completion timed out\n", 0ULL); -#ifdef HSI_SUPPORT - if (osi_core->hsi.enabled == OSI_ENABLE) { - osi_core->hsi.err_code[AUTONEG_ERR_IDX] = - OSI_PCS_AUTONEG_ERR; - osi_core->hsi.report_err = OSI_ENABLE; - osi_core->hsi.report_count_err[AUTONEG_ERR_IDX] = OSI_ENABLE; - } -#endif - return -1; - } - - count++; - - status = xpcs_read(xpcs_base, XPCS_VR_MII_AN_INTR_STS); - if ((status & XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR) == 0U) { - /* autoneg not completed - poll */ - osi_core->osd_ops.udelay(1000U); - } else { - /* 15. clear interrupt */ - status &= ~XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR; - ret = xpcs_write_safety(osi_core, XPCS_VR_MII_AN_INTR_STS, status); - if (ret != 0) { - return ret; - } - cond = 0; - } - } - - if ((status & XPCS_USXG_AN_STS_SPEED_MASK) == 0U) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "XPCS AN completed with zero speed\n", 0ULL); - return -1; - } - - *an_status = status; - return 0; -} - -/** - * @brief xpcs_set_speed - Set speed at XPCS - * - * Algorithm: This routine program XPCS speed based on AN status. - * - * @param[in] osi_core: OSI core data structure. - * @param[in] status: Autonegotation Status. - * - * @retval 0 on success - * @retval -1 on failure - */ -static inline int xpcs_set_speed(struct osi_core_priv_data *osi_core, - unsigned int status) -{ - unsigned int speed = status & XPCS_USXG_AN_STS_SPEED_MASK; - unsigned int ctrl = 0; - void *xpcs_base = osi_core->xpcs_base; - - ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); - - switch (speed) { - case XPCS_USXG_AN_STS_SPEED_2500: - /* 2.5Gbps */ - ctrl |= XPCS_SR_MII_CTRL_SS5; - ctrl &= ~(XPCS_SR_MII_CTRL_SS6 | XPCS_SR_MII_CTRL_SS13); - break; - case XPCS_USXG_AN_STS_SPEED_5000: - /* 5Gbps */ - ctrl |= (XPCS_SR_MII_CTRL_SS5 | XPCS_SR_MII_CTRL_SS13); - ctrl &= ~XPCS_SR_MII_CTRL_SS6; - break; - case XPCS_USXG_AN_STS_SPEED_10000: - default: - /* 10Gbps */ - ctrl |= (XPCS_SR_MII_CTRL_SS6 | XPCS_SR_MII_CTRL_SS13); - ctrl &= ~XPCS_SR_MII_CTRL_SS5; - break; - } - - return xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl); -} - -/** - * @brief xpcs_start - Start XPCS - * - * Algorithm: This routine enables AN and set speed based on AN status - * - * @param[in] osi_core: OSI core data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -int xpcs_start(struct osi_core_priv_data *osi_core) -{ - void *xpcs_base = osi_core->xpcs_base; - unsigned int an_status = 0; - unsigned int retry = RETRY_COUNT; - unsigned int count = 0; - unsigned int ctrl = 0; - int ret = 0; - int cond = COND_NOT_MET; - - if (osi_core->xpcs_base == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "XPCS base is NULL", 0ULL); - /* TODO: Remove this once silicon arrives */ - return 0; - } - - if ((osi_core->phy_iface_mode == OSI_USXGMII_MODE_10G) || - (osi_core->phy_iface_mode == OSI_USXGMII_MODE_5G)) { - ctrl = xpcs_read(xpcs_base, XPCS_SR_MII_CTRL); - ctrl |= XPCS_SR_MII_CTRL_AN_ENABLE; - ret = xpcs_write_safety(osi_core, XPCS_SR_MII_CTRL, ctrl); - if (ret != 0) { - return ret; - } - ret = xpcs_poll_for_an_complete(osi_core, &an_status); - if (ret < 0) { - return ret; - } - - ret = xpcs_set_speed(osi_core, an_status); - if (ret != 0) { - return ret; - } - /* USXGMII Rate Adaptor Reset before data transfer */ - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_USRA_RST; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); - while (cond == COND_NOT_MET) { - if (count > retry) { - return -1; - } - - count++; - - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - if ((ctrl & XPCS_VR_XS_PCS_DIG_CTRL1_USRA_RST) == 0U) { - cond = COND_MET; - } else { - osi_core->osd_ops.udelay(1000U); - } - } - } - - /* poll for Rx link up */ - cond = COND_NOT_MET; - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - return -1; - } - - count++; - - ctrl = xpcs_read(xpcs_base, XPCS_SR_XS_PCS_STS1); - if ((ctrl & XPCS_SR_XS_PCS_STS1_RLU) == - XPCS_SR_XS_PCS_STS1_RLU) { - cond = COND_MET; - } else { - osi_core->osd_ops.udelay(1000U); - } - } - - return 0; -} - -/** - * @brief xpcs_uphy_lane_bring_up - Bring up UPHY Tx/Rx lanes - * - * Algorithm: This routine bring up the UPHY Tx/Rx lanes - * through XPCS FSM wrapper. - * - * @param[in] osi_core: OSI core data structure. - * @param[in] lane_init_en: Tx/Rx lane init value. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t xpcs_uphy_lane_bring_up(struct osi_core_priv_data *osi_core, - unsigned int lane_init_en) -{ - void *xpcs_base = osi_core->xpcs_base; - nveu32_t retry = XPCS_RETRY_COUNT; - nve32_t cond = COND_NOT_MET; - nveu32_t val = 0; - nveu32_t count; - - val = osi_readla(osi_core, - (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_STATUS); - if ((val & XPCS_WRAP_UPHY_STATUS_TX_P_UP_STATUS) == - XPCS_WRAP_UPHY_STATUS_TX_P_UP_STATUS) { - /* return success if TX lane is already UP */ - return 0; - } - - val = osi_readla(osi_core, - (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_HW_INIT_CTRL); - val |= lane_init_en; - osi_writela(osi_core, val, - (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_HW_INIT_CTRL); - - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - return -1; - } - count++; - - val = osi_readla(osi_core, - (nveu8_t *)xpcs_base + XPCS_WRAP_UPHY_HW_INIT_CTRL); - if ((val & lane_init_en) == OSI_NONE) { - /* exit loop */ - cond = COND_MET; - } else { - osi_core->osd_ops.udelay(500U); - } - } - - return 0; -} - -/** - * @brief xpcs_check_pcs_lock_status - Checks whether PCS lock happened or not. - * - * Algorithm: This routine helps to check whether PCS lock happened or not. - * - * @param[in] osi_core: OSI core data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t xpcs_check_pcs_lock_status(struct osi_core_priv_data *osi_core) -{ - void *xpcs_base = osi_core->xpcs_base; - nveu32_t retry = XPCS_RETRY_COUNT; - nve32_t cond = COND_NOT_MET; - nveu32_t val = 0; - nveu32_t count; - - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - return -1; - } - count++; - - val = osi_readla(osi_core, - (nveu8_t *)xpcs_base + XPCS_WRAP_IRQ_STATUS); - if ((val & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS) == - XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS) { - /* exit loop */ - cond = COND_MET; - } else { - osi_core->osd_ops.udelay(500U); - } - } - - /* Clear the status */ - osi_writela(osi_core, val, (nveu8_t *)xpcs_base + XPCS_WRAP_IRQ_STATUS); - - return 0; -} - -/** - * @brief xpcs_lane_bring_up - Bring up UPHY Tx/Rx lanes - * - * Algorithm: This routine bring up the UPHY Tx/Rx lanes - * through XPCS FSM wrapper. - * - * @param[in] osi_core: OSI core data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t xpcs_lane_bring_up(struct osi_core_priv_data *osi_core) -{ - unsigned int retry = 1000; - unsigned int count; - nveu32_t val = 0; - int cond; - - if (xpcs_uphy_lane_bring_up(osi_core, - XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "UPHY TX lane bring-up failed\n", 0ULL); - return -1; - } - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step1 RX_SW_OVRD */ - val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SW_OVRD; - osi_writela(osi_core, val, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step2 RX_IDDQ */ - val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_IDDQ); - osi_writela(osi_core, val, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step2 AUX_RX_IDDQ */ - val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_AUX_RX_IDDQ); - osi_writela(osi_core, val, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step3 RX_SLEEP */ - val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SLEEP); - osi_writela(osi_core, val, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step4 RX_CAL_EN */ - val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN; - osi_writela(osi_core, val, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - /* Step5 poll for Rx cal enable */ - cond = COND_NOT_MET; - count = 0; - while (cond == COND_NOT_MET) { - if (count > retry) { - return -1; - } - - count++; - - val = osi_readla(osi_core, - (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - if ((val & XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN) == 0) { - cond = COND_MET; - } else { - osi_core->osd_ops.udelay(1000U); - } - } - - /* Step6 RX_DATA_EN */ - val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_DATA_EN; - osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - /* Step7 RX_CDR_RESET */ - val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET; - osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - /* Step8 RX_CDR_RESET */ - val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - val &= ~(XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET); - osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - val = osi_readla(osi_core, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - /* Step9 RX_PCS_PHY_RDY */ - val |= XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_PCS_PHY_RDY; - osi_writela(osi_core, val, (nveu8_t *)osi_core->xpcs_base + - XPCS_WRAP_UPHY_RX_CONTROL_0_0); - - if (xpcs_check_pcs_lock_status(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "Failed to get PCS block lock\n", 0ULL); - return -1; - } - - return 0; -} - -/** - * @brief xpcs_init - XPCS initialization - * - * Algorithm: This routine initialize XPCS in USXMII mode. - * - * @param[in] osi_core: OSI core data structure. - * - * @retval 0 on success - * @retval -1 on failure. - */ -int xpcs_init(struct osi_core_priv_data *osi_core) -{ - void *xpcs_base = osi_core->xpcs_base; - unsigned int retry = 1000; - unsigned int count; - unsigned int ctrl = 0; - int cond = 1; - int ret = 0; - - if (osi_core->xpcs_base == OSI_NULL) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "XPCS base is NULL", 0ULL); - /* TODO: Remove this once silicon arrives */ - return 0; - } - - if (osi_core->pre_si != OSI_ENABLE) { - if (xpcs_lane_bring_up(osi_core) < 0) { - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "TX/RX lane bring-up failed\n", 0ULL); - return -1; - } - } - - /* Switching to USXGMII Mode based on - * XPCS programming guideline 7.6 - */ - - /* 1. switch DWC_xpcs to BASE-R mode */ - ctrl = xpcs_read(xpcs_base, XPCS_SR_XS_PCS_CTRL2); - ctrl |= XPCS_SR_XS_PCS_CTRL2_PCS_TYPE_SEL_BASE_R; - ret = xpcs_write_safety(osi_core, XPCS_SR_XS_PCS_CTRL2, ctrl); - if (ret != 0) { - return ret; - } - /* 2. enable USXGMII Mode inside DWC_xpcs */ - - /* 3. USXG_MODE = 10G - default it will be 10G mode */ - if ((osi_core->phy_iface_mode == OSI_USXGMII_MODE_10G) || - (osi_core->phy_iface_mode == OSI_USXGMII_MODE_5G)) { - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_KR_CTRL); - ctrl &= ~(XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_MASK); - - if (osi_core->uphy_gbe_mode == OSI_DISABLE) { - ctrl |= XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_5G; - } - } - - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_KR_CTRL, ctrl); - if (ret != 0) { - return ret; - } - /* 4. Program PHY to operate at 10Gbps/5Gbps/2Gbps - * this step not required since PHY speed programming - * already done as part of phy INIT - */ - /* 5. Vendor specific software reset */ - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_USXG_EN; - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); - if (ret != 0) { - return ret; - } - - /* XPCS_VR_XS_PCS_DIG_CTRL1_VR_RST bit is self clearing - * value readback varification is not needed - */ - ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_VR_RST; - xpcs_write(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); - - /* 6. Programming for Synopsys PHY - NA */ - - /* 7. poll until vendor specific software reset */ - cond = 1; - count = 0; - while (cond == 1) { - if (count > retry) { - return -1; - } - - count++; - - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - if ((ctrl & XPCS_VR_XS_PCS_DIG_CTRL1_VR_RST) == 0U) { - cond = 0; - } else { - osi_core->osd_ops.udelay(1000U); - } - } - - /* 8. Backplane Ethernet PCS configurations - * clear AN_EN in SR_AN_CTRL - * set CL37_BP in VR_XS_PCS_DIG_CTRL1 - */ - if ((osi_core->phy_iface_mode == OSI_USXGMII_MODE_10G) || - (osi_core->phy_iface_mode == OSI_USXGMII_MODE_5G)) { - ctrl = xpcs_read(xpcs_base, XPCS_SR_AN_CTRL); - ctrl &= ~XPCS_SR_AN_CTRL_AN_EN; - ret = xpcs_write_safety(osi_core, XPCS_SR_AN_CTRL, ctrl); - if (ret != 0) { - return ret; - } - ctrl = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_DIG_CTRL1); - ctrl |= XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP; - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_DIG_CTRL1, ctrl); - if (ret != 0) { - return ret; - } - } - - /* TODO: 9. MII_AN_INTR_EN to 1, to enable auto-negotiation - * complete interrupt */ - - /* 10. (Optional step) Duration of link timer change */ - - /* 11. XPCS configured as MAC-side USGMII - NA */ - - /* 13. TODO: If there is interrupt enabled for AN interrupt */ - - return 0; -} - -/** - * @brief xpcs_eee - XPCS enable/disable EEE - * - * Algorithm: This routine update register related to EEE - * for XPCS. - * - * @param[in] osi_core: OSI core data structure. - * @param[in] en_dis: enable - 1 or disable - 0 - * - * @retval 0 on success - * @retval -1 on failure. - */ -int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis) -{ - void *xpcs_base = osi_core->xpcs_base; - unsigned int val = 0x0U; - int ret = 0; - - if (en_dis != OSI_ENABLE && en_dis != OSI_DISABLE) { - return -1; - } - - if (xpcs_base == OSI_NULL) - return -1; - - if (en_dis == OSI_DISABLE) { - val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0); - val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN; - val &= ~XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN; - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val); - if (ret != 0) { - return ret; - } - return 0; - } - - /* 1. Check if DWC_xpcs supports the EEE feature by - * reading the SR_XS_PCS_EEE_ABL register - * 1000BASEX-Only is different config then else so can (skip) */ - - /* 2. Program various timers used in the EEE mode depending on the - * clk_eee_i clock frequency. default times are same as IEEE std - * clk_eee_i() is 102MHz. MULT_FACT_100NS = 9 because 9.8ns*10 = 98 - * which is between 80 and 120 this leads to default setting match */ - - val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL0); - /* 3. If FEC is enabled in the KR mode (skip in FPGA)*/ - /* 4. enable the EEE feature on the Tx path and Rx path */ - val |= (XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN | - XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN); - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL0, val); - if (ret != 0) { - return ret; - } - /* Transparent Tx LPI Mode Enable */ - val = xpcs_read(xpcs_base, XPCS_VR_XS_PCS_EEE_MCTRL1); - val |= XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI; - ret = xpcs_write_safety(osi_core, XPCS_VR_XS_PCS_EEE_MCTRL1, val); - if (ret != 0) { - return ret; - } - return 0; -} diff --git a/osi/core/xpcs.h b/osi/core/xpcs.h deleted file mode 100644 index 070e441..0000000 --- a/osi/core/xpcs.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 XPCS_H_ -#define XPCS_H_ - -#include "../osi/common/common.h" -#include - -/** - * @addtogroup XPCS helper macros - * - * @brief XPCS helper macros. - * @{ - */ -#define XPCS_RETRY_COUNT (RETRY_COUNT * (2U)) -/** @} */ - -/** - * @addtogroup XPCS Register offsets - * - * @brief XPCS register offsets - * @{ - */ -#define XPCS_ADDRESS 0x03FC -#define XPCS_SR_XS_PCS_CTRL1 0xC0000 -#define XPCS_SR_XS_PCS_STS1 0xC0004 -#define XPCS_SR_XS_PCS_CTRL2 0xC001C -#define XPCS_SR_XS_PCS_EEE_ABL 0xC0050 -#define XPCS_SR_XS_PCS_EEE_ABL2 0xC0054 -#define XPCS_VR_XS_PCS_DIG_CTRL1 0xE0000 -#define XPCS_VR_XS_PCS_KR_CTRL 0xE001C -#define XPCS_SR_AN_CTRL 0x1C0000 -#define XPCS_SR_MII_CTRL 0x7C0000 -#define XPCS_VR_MII_AN_INTR_STS 0x7E0008 -#define XPCS_VR_XS_PCS_EEE_MCTRL0 0xE0018 -#define XPCS_VR_XS_PCS_EEE_MCTRL1 0xE002C -#define XPCS_WRAP_UPHY_HW_INIT_CTRL 0x8020 -#define XPCS_WRAP_UPHY_STATUS 0x8044 -#define XPCS_WRAP_IRQ_STATUS 0x8050 -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0 0x801C -/** @} */ - - -/** - * @addtogroup XPCS-BIT Register bit fileds - * - * @brief XPCS register bit fields - * @{ - */ -#define XPCS_SR_XS_PCS_CTRL1_RST OSI_BIT(15) -#define XPCS_SR_XS_PCS_CTRL2_PCS_TYPE_SEL_BASE_R 0x0U -#define XPCS_SR_XS_PCS_STS1_RLU OSI_BIT(2) -#define XPCS_VR_XS_PCS_DIG_CTRL1_USXG_EN OSI_BIT(9) -#define XPCS_VR_XS_PCS_DIG_CTRL1_VR_RST OSI_BIT(15) -#define XPCS_VR_XS_PCS_DIG_CTRL1_USRA_RST OSI_BIT(10) -#define XPCS_VR_XS_PCS_DIG_CTRL1_CL37_BP OSI_BIT(12) -#define XPCS_VR_XS_PCS_EEE_MCTRL1_TRN_LPI OSI_BIT(0) -#define XPCS_VR_XS_PCS_EEE_MCTRL0_LTX_EN OSI_BIT(0) -#define XPCS_VR_XS_PCS_EEE_MCTRL0_LRX_EN OSI_BIT(1) -#define XPCS_SR_AN_CTRL_AN_EN OSI_BIT(12) -#define XPCS_SR_MII_CTRL_AN_ENABLE OSI_BIT(12) -#define XPCS_VR_MII_AN_INTR_STS_CL37_ANCMPLT_INTR OSI_BIT(0) -#define XPCS_SR_MII_CTRL_SS5 OSI_BIT(5) -#define XPCS_SR_MII_CTRL_SS6 OSI_BIT(6) -#define XPCS_SR_MII_CTRL_SS13 OSI_BIT(13) -#define XPCS_USXG_AN_STS_SPEED_MASK 0x1C00U -#define XPCS_USXG_AN_STS_SPEED_2500 0x1000U -#define XPCS_USXG_AN_STS_SPEED_5000 0x1400U -#define XPCS_USXG_AN_STS_SPEED_10000 0xC00U -#define XPCS_REG_ADDR_SHIFT 10U -#define XPCS_REG_ADDR_MASK 0x1FFFU -#define XPCS_REG_VALUE_MASK 0x3FFU -#define XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_MASK (OSI_BIT(12) | \ - OSI_BIT(11) | \ - OSI_BIT(10)) -#define XPCS_VR_XS_PCS_KR_CTRL_USXG_MODE_5G OSI_BIT(10) -#define XPCS_WRAP_UPHY_HW_INIT_CTRL_TX_EN OSI_BIT(0) -#define XPCS_WRAP_UPHY_HW_INIT_CTRL_RX_EN OSI_BIT(2) -#define XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS OSI_BIT(6) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_DATA_EN OSI_BIT(0) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_IDDQ OSI_BIT(4) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_AUX_RX_IDDQ OSI_BIT(5) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SLEEP (OSI_BIT(6) | \ - OSI_BIT(7)) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CAL_EN OSI_BIT(8) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_CDR_RESET OSI_BIT(9) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_PCS_PHY_RDY OSI_BIT(10) -#define XPCS_WRAP_UPHY_RX_CONTROL_0_0_RX_SW_OVRD OSI_BIT(31) -#define XPCS_WRAP_UPHY_STATUS_TX_P_UP_STATUS OSI_BIT(0) - -#ifdef HSI_SUPPORT -#define XPCS_WRAP_INTERRUPT_CONTROL 0x8048 -#define XPCS_WRAP_INTERRUPT_STATUS 0x8050 -#define XPCS_CORE_CORRECTABLE_ERR OSI_BIT(10) -#define XPCS_CORE_UNCORRECTABLE_ERR OSI_BIT(9) -#define XPCS_REGISTER_PARITY_ERR OSI_BIT(8) -#define XPCS_BASE_PMA_MMD_SR_PMA_KR_FEC_CTRL 0x402AC -#define EN_ERR_IND OSI_BIT(1) -#define FEC_EN OSI_BIT(0) -#define XPCS_VR_XS_PCS_SFTY_UE_INTR0 0xE03C0 -#define XPCS_VR_XS_PCS_SFTY_CE_INTR 0xE03C8 -#define XPCS_VR_XS_PCS_SFTY_TMR_CTRL 0xE03D4 -#define XPCS_SFTY_1US_MULT_MASK 0xFF -#define XPCS_SFTY_1US_MULT_SHIFT 0U -#endif -/** @} */ - -int xpcs_init(struct osi_core_priv_data *osi_core); -int xpcs_start(struct osi_core_priv_data *osi_core); -int xpcs_eee(struct osi_core_priv_data *osi_core, unsigned int en_dis); - -/** - * @brief xpcs_read - read from xpcs. - * - * Algorithm: This routine reads data from XPCS register. - * - * @param[in] xpcs_base: XPCS virtual base address - * @param[in] reg_addr: register address to be read - * - * @retval value read from xpcs register. - */ -static inline unsigned int xpcs_read(void *xpcs_base, unsigned int reg_addr) -{ - osi_writel(((reg_addr >> XPCS_REG_ADDR_SHIFT) & XPCS_REG_ADDR_MASK), - ((unsigned char *)xpcs_base + XPCS_ADDRESS)); - return osi_readl((unsigned char *)xpcs_base + - ((reg_addr) & XPCS_REG_VALUE_MASK)); -} - -/** - * @brief xpcs_write - write to xpcs. - * - * Algorithm: This routine writes data to XPCS register. - * - * @param[in] xpcs_base: XPCS virtual base address - * @param[in] reg_addr: register address for writing - * @param[in] val: write value to register address - */ -static inline void xpcs_write(void *xpcs_base, unsigned int reg_addr, - unsigned int val) -{ - osi_writel(((reg_addr >> XPCS_REG_ADDR_SHIFT) & XPCS_REG_ADDR_MASK), - ((unsigned char *)xpcs_base + XPCS_ADDRESS)); - osi_writel(val, (unsigned char *)xpcs_base + - (((reg_addr) & XPCS_REG_VALUE_MASK))); -} - -/** - * @brief xpcs_write_safety - write to xpcs. - * - * Algorithm: This routine writes data to XPCS register. - * And verifiy by reading back the value - * - * @param[in] osi_core: OSI core data structure - * @param[in] reg_addr: register address for writing - * @param[in] val: write value to register address - * - * @retval 0 on success - * @retval -1 on failure. - * - */ -static inline int xpcs_write_safety(struct osi_core_priv_data *osi_core, - unsigned int reg_addr, - unsigned int val) -{ - void *xpcs_base = osi_core->xpcs_base; - unsigned int read_val; - int retry = 10; - - while (--retry > 0) { - xpcs_write(xpcs_base, reg_addr, val); - read_val = xpcs_read(xpcs_base, reg_addr); - if (val == read_val) { - return 0; - } - osi_core->osd_ops.udelay(OSI_DELAY_1US); - } - - OSI_CORE_ERR(OSI_NULL, OSI_LOG_ARG_HW_FAIL, - "xpcs_write_safety failed", reg_addr); - return -1; -} -#endif diff --git a/osi/dma/Makefile.interface.tmk b/osi/dma/Makefile.interface.tmk deleted file mode 100644 index c12901e..0000000 --- a/osi/dma/Makefile.interface.tmk +++ /dev/null @@ -1,39 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 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. -# -# libnvethernetcl interface makefile fragment -# -############################################################################### - -ifdef NV_INTERFACE_FLAG_SHARED_LIBRARY_SECTION -NV_INTERFACE_NAME := nvethernetcl -NV_INTERFACE_EXPORTS := lib$(NV_INTERFACE_NAME) -NV_INTERFACE_PUBLIC_INCLUDES := \ - ./include -endif - - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 8 -# End: -# vi: set tabstop=8 noexpandtab: diff --git a/osi/dma/Makefile.tmk b/osi/dma/Makefile.tmk deleted file mode 100644 index 7e1e52d..0000000 --- a/osi/dma/Makefile.tmk +++ /dev/null @@ -1,61 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 2019-2022, 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. -# -############################################################################### - -ifdef NV_COMPONENT_FLAG_SHARED_LIBRARY_SECTION -include $(NV_BUILD_START_COMPONENT) - -NV_COMPONENT_STRICT_WARNINGS_qnx_64 := 1 - -NV_COMPONENT_NAME := nvethernetcl -NV_COMPONENT_OWN_INTERFACE_DIR := . -NV_COMPONENT_SOURCES := \ - eqos_dma.c \ - osi_dma.c \ - osi_dma_txrx.c \ - mgbe_dma.c \ - eqos_desc.c \ - mgbe_desc.c \ - debug.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/osi_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/eqos_common.c \ - $(NV_SOURCE)/nvethernetrm/osi/common/mgbe_common.c - -NV_COMPONENT_INCLUDES := \ - $(NV_SOURCE)/nvethernetrm/include \ - $(NV_SOURCE)/nvethernetrm/osi/common/include - -ifeq ($(NV_BUILD_CONFIGURATION_IS_SAFETY),0) -NV_COMPONENT_CFLAGS += -DOSI_DEBUG -endif - - -include $(NV_BUILD_SHARED_LIBRARY) -endif - - -# Local Variables: -# indent-tabs-mode: t -# tab-width: 8 -# End: -# vi: set tabstop=8 noexpandtab: diff --git a/osi/dma/debug.c b/osi/dma/debug.c deleted file mode 100644 index 3ccb451..0000000 --- a/osi/dma/debug.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2021-2022, 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. - */ - -#ifdef OSI_DEBUG -#include "debug.h" - -/** - * @brief dump_struct - Dumps a given structure. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] ptr: Pointer to structure. - * @param[in] size: Size of structure to dump. - * - */ -static void dump_struct(struct osi_dma_priv_data *osi_dma, - unsigned char *ptr, - unsigned long size) -{ - nveu32_t i = 0, rem, j; - unsigned long temp; - - if (ptr == OSI_NULL) { - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "Pointer is NULL\n"); - return; - } - - rem = i % 4; - temp = size - rem; - - for (i = 0; i < temp; i += 4) { - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "%02x%02x%02x%02x", ptr[i], ptr[i + 1], - ptr[i + 2], ptr[i + 3]); - j = i; - } - - for (i = j; i < size; i++) { - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, "%x", - ptr[i]); - } -} - -/** - * @brief structs_dump - Dumps OSI DMA structure. - * - * @param[in] osi_dma: OSI DMA private data structure. - */ -void structs_dump(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t i = 0; - - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "OSI DMA struct size: %lu", - sizeof(struct osi_dma_priv_data)); - dump_struct(osi_dma, (unsigned char *)osi_dma, - sizeof(struct osi_dma_priv_data)); - - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "OSI DMA Tx/Rx Ring struct sizes: %lu %lu", - sizeof(struct osi_tx_ring), - sizeof(struct osi_rx_ring)); - for (i = 0; i < osi_dma->num_dma_chans; i++) { - dump_struct(osi_dma, (unsigned char *)osi_dma->tx_ring[i], - sizeof(struct osi_tx_ring)); - dump_struct(osi_dma, (unsigned char *)osi_dma->rx_ring[i], - sizeof(struct osi_rx_ring)); - } - - - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "OSD DMA ops struct size: %lu", - sizeof(struct osd_dma_ops)); - dump_struct(osi_dma, (unsigned char *)(&osi_dma->osd_ops), - sizeof(struct osd_dma_ops)); - - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "OSI local DMA struct size: %lu", - sizeof(struct dma_local)); - dump_struct(osi_dma, (unsigned char *)l_dma, - sizeof(struct dma_local)); - - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_STRUCTS, - "OSI local ops DMA struct size: %lu", - sizeof(struct dma_chan_ops)); - dump_struct(osi_dma, (unsigned char *)l_dma->ops_p, - sizeof(struct dma_chan_ops)); -} - -/** - * @brief reg_dump - Dumps MAC DMA registers - * - * @param[in] osi_dma: OSI DMA private data structure. - */ -void reg_dump(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - unsigned int max_addr; - unsigned int addr; - unsigned int reg_val; - - switch (l_dma->mac_ver) { - case OSI_EQOS_MAC_5_00: - addr = 0x1100; - max_addr = 0x12E4; - break; - case OSI_EQOS_MAC_5_30: - addr = 0x116C; - max_addr = 0x14EC; - break; - case OSI_MGBE_MAC_3_10: - case OSI_MGBE_MAC_4_00: - addr = 0x3100; - max_addr = 0x35FC; - break; - default: - return; - } - - while (1) { - if (addr > max_addr) - break; - - reg_val = osi_readl((nveu8_t *)osi_dma->base + addr); - osi_dma->osd_ops.printf(osi_dma, OSI_DEBUG_TYPE_REG, - "%x: %x\n", addr, reg_val); - addr += 4; - } -} - -/** - * @brief rx_desc_dump - Function to dump Rx descriptors - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] idx: Index to be dumped in Rx ring. - * @param[in] chan: DMA channel number - */ -static void rx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int idx, - unsigned int chan) -{ - struct osi_rx_ring *rx_ring = osi_dma->rx_ring[chan]; - struct osi_rx_desc *rx_desc = rx_ring->rx_desc + idx; - struct osd_dma_ops *ops = &osi_dma->osd_ops; - - ops->printf(osi_dma, OSI_DEBUG_TYPE_DESC, - "N [%02d %4p %04d %lx R_D] = %#x:%#x:%#x:%#x\n", - chan, rx_desc, idx, - (rx_ring->rx_desc_phy_addr + (idx * sizeof(struct osi_rx_desc))), - rx_desc->rdes3, rx_desc->rdes2, - rx_desc->rdes1, rx_desc->rdes0); - -} - -/** - * @brief tx_desc_dump - Function to dump Tx descriptors - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] f_idx: First index to be dumped in Tx ring. - * @param[in] l_idx: Last index to be dumped in Tx ring. - * @param[in] tx: Represents whether packet queued for tx done. - * @param[in] chan: DMA channel number - */ -static void tx_desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, - unsigned int l_idx, unsigned int tx, - unsigned int chan) -{ - struct osi_tx_ring *tx_ring = osi_dma->tx_ring[chan]; - struct osi_tx_desc *tx_desc = OSI_NULL; - struct osd_dma_ops *ops = &osi_dma->osd_ops; - unsigned int ctxt = 0, i = 0; - - if (f_idx == l_idx) { - tx_desc = tx_ring->tx_desc + f_idx; - ctxt = tx_desc->tdes3 & TDES3_CTXT; - - ops->printf(osi_dma, OSI_DEBUG_TYPE_DESC, - "%s [%02d %4p %04d %lx %s] = %#x:%#x:%#x:%#x\n", - (ctxt == TDES3_CTXT) ? "C" : "N", - chan, tx_desc, f_idx, - (tx_ring->tx_desc_phy_addr + (f_idx * sizeof(struct osi_tx_desc))), - (tx == TX_DESC_DUMP_TX) ? "T_Q" : "T_D", - tx_desc->tdes3, tx_desc->tdes2, - tx_desc->tdes1, tx_desc->tdes0); - } else { - int cnt; - - if (f_idx > l_idx) { - cnt = l_idx + osi_dma->tx_ring_sz - f_idx; - } else { - cnt = l_idx - f_idx; - } - - for (i = f_idx; cnt >= 0; cnt--) { - tx_desc = tx_ring->tx_desc + i; - ctxt = tx_desc->tdes3 & TDES3_CTXT; - - ops->printf(osi_dma, OSI_DEBUG_TYPE_DESC, - "%s [%02d %4p %04d %lx %s] = %#x:%#x:%#x:%#x\n", - (ctxt == TDES3_CTXT) ? "C" : "N", - chan, tx_desc, i, - (tx_ring->tx_desc_phy_addr + (i * sizeof(struct osi_tx_desc))), - (tx == TX_DESC_DUMP_TX) ? "T_Q" : "T_D", - tx_desc->tdes3, tx_desc->tdes2, - tx_desc->tdes1, tx_desc->tdes0); - - INCR_TX_DESC_INDEX(i, osi_dma->tx_ring_sz); - } - } -} - -/** - * @brief desc_dump - Function to dump Tx/Rx descriptors - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] f_idx: First index to be dumped in Tx/Rx ring. - * @param[in] l_idx: Last index to be dumped in Tx/Rx ring. - * @param[in] flag: Flags to indicate Tx/Tx done or Rx. - * @param[in] chan: DMA channel number - * - */ -void desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, - unsigned int l_idx, unsigned int flag, unsigned int chan) -{ - switch (flag & TXRX_DESC_DUMP_MASK) { - case TX_DESC_DUMP: - tx_desc_dump(osi_dma, f_idx, l_idx, - (flag & TX_DESC_DUMP_MASK), chan); - break; - case RX_DESC_DUMP: - rx_desc_dump(osi_dma, f_idx, chan); - break; - default: - break; - } -} -#endif /* OSI_DEBUG */ diff --git a/osi/dma/debug.h b/osi/dma/debug.h deleted file mode 100644 index aca3739..0000000 --- a/osi/dma/debug.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021, 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 INCLUDED_DMA_DEBUG_H -#define INCLUDED_DMA_DEBUG_H - -#include -#include -#include "hw_desc.h" -#include "../osi/common/common.h" -#include "dma_local.h" - -/** - * @addtogroup DESC-DUMP helper macros. - * - * @brief Helper macros used for debugging. - * @{ - */ -#define TX_DESC_DUMP OSI_BIT(0) -#define RX_DESC_DUMP OSI_BIT(1) -#define TXRX_DESC_DUMP_MASK (OSI_BIT(0) | OSI_BIT(1)) -#define TX_DESC_DUMP_TX OSI_BIT(2) -#define TX_DESC_DUMP_TX_DONE OSI_BIT(3) -#define TX_DESC_DUMP_MASK (OSI_BIT(2) | OSI_BIT(3)) -/** @} */ - -void desc_dump(struct osi_dma_priv_data *osi_dma, unsigned int f_idx, - unsigned int l_idx, unsigned int flag, unsigned int chan); -void reg_dump(struct osi_dma_priv_data *osi_dma); -void structs_dump(struct osi_dma_priv_data *osi_dma); -#endif /* INCLUDED_DMA_DEBUG_H*/ diff --git a/osi/dma/dma_local.h b/osi/dma/dma_local.h deleted file mode 100644 index 465fd03..0000000 --- a/osi/dma/dma_local.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2019-2022, 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 INCLUDED_DMA_LOCAL_H -#define INCLUDED_DMA_LOCAL_H - -#include -#include "eqos_dma.h" - -/** - * @brief Maximum number of OSI DMA instances. - */ -#ifndef MAX_DMA_INSTANCES -#define MAX_DMA_INSTANCES 10U -#endif - -/** - * @brief Default DMA Tx/Rx ring sizes for EQOS/MGBE. - */ -#define EQOS_DEFAULT_RING_SZ 1024U -#define MGBE_DEFAULT_RING_SZ 4096U -#define MGBE_MAX_RING_SZ 16384U -#define HW_MIN_RING_SZ 4U - -/** - * @brief MAC DMA Channel operations - */ -struct dma_chan_ops { - /** Called to set Transmit Ring length */ - void (*set_tx_ring_len)(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len); - /** Called to set Transmit Ring Base address */ - void (*set_tx_ring_start_addr)(void *addr, nveu32_t chan, - nveu64_t base_addr); - /** Called to update Tx Ring tail pointer */ - void (*update_tx_tailptr)(void *addr, nveu32_t chan, - nveu64_t tailptr); - /** Called to set Receive channel ring length */ - void (*set_rx_ring_len)(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len); - /** Called to set receive channel ring base address */ - void (*set_rx_ring_start_addr)(void *addr, nveu32_t chan, - nveu64_t base_addr); - /** Called to update Rx ring tail pointer */ - void (*update_rx_tailptr)(void *addr, nveu32_t chan, - nveu64_t tailptr); - /** Called to disable DMA Tx channel interrupts at wrapper level */ - void (*disable_chan_tx_intr)(void *addr, nveu32_t chan); - /** Called to enable DMA Tx channel interrupts at wrapper level */ - void (*enable_chan_tx_intr)(void *addr, nveu32_t chan); - /** Called to disable DMA Rx channel interrupts at wrapper level */ - void (*disable_chan_rx_intr)(void *addr, nveu32_t chan); - /** Called to enable DMA Rx channel interrupts at wrapper level */ - void (*enable_chan_rx_intr)(void *addr, nveu32_t chan); - /** Called to start the Tx/Rx DMA */ - void (*start_dma)(struct osi_dma_priv_data *osi_dma, nveu32_t chan); - /** Called to stop the Tx/Rx DMA */ - void (*stop_dma)(struct osi_dma_priv_data *osi_dma, nveu32_t chan); - /** Called to initialize the DMA channel */ - nve32_t (*init_dma_channel)(struct osi_dma_priv_data *osi_dma); - /** Called to set Rx buffer length */ - void (*set_rx_buf_len)(struct osi_dma_priv_data *osi_dma); -#ifndef OSI_STRIPPED_LIB - /** Called periodically to read and validate safety critical - * registers against last written value */ - nve32_t (*validate_regs)(struct osi_dma_priv_data *osi_dma); - /** Called to configure the DMA channel slot function */ - void (*config_slot)(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t set, - nveu32_t interval); -#endif /* !OSI_STRIPPED_LIB */ - /** Called to clear VM Tx interrupt */ - void (*clear_vm_tx_intr)(void *addr, nveu32_t chan); - /** Called to clear VM Rx interrupt */ - void (*clear_vm_rx_intr)(void *addr, nveu32_t chan); -}; - -/** - * @brief DMA descriptor operations - */ -struct desc_ops { - /** Called to get receive checksum */ - void (*get_rx_csum)(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx); - /** Called to get rx error stats */ - void (*update_rx_err_stats)(struct osi_rx_desc *rx_desc, - struct osi_pkt_err_stats *stats); - /** Called to get rx VLAN from descriptor */ - void (*get_rx_vlan)(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx); - /** Called to get rx HASH from descriptor */ - void (*get_rx_hash)(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx); - /** Called to get RX hw timestamp */ - int (*get_rx_hwstamp)(struct osi_dma_priv_data *osi_dma, - struct osi_rx_desc *rx_desc, - struct osi_rx_desc *context_desc, - struct osi_rx_pkt_cx *rx_pkt_cx); -}; - -/** - * @brief OSI DMA private data. - */ -struct dma_local { - /** OSI DMA data variable */ - struct osi_dma_priv_data osi_dma; - /** DMA channel operations */ - struct dma_chan_ops *ops_p; - /** - * PacketID for PTP TS. - * MSB 4-bits of channel number and LSB 6-bits of local - * index(PKT_ID_CNT). - */ - nveu32_t pkt_id; - /** Flag to represent OSI DMA software init done */ - nveu32_t init_done; - /** Holds the MAC version of MAC controller */ - nveu32_t mac_ver; - /** Represents whether DMA interrupts are VM or Non-VM */ - nveu32_t vm_intr; - /** Magic number to validate osi_dma pointer */ - nveu64_t magic_num; - /** Maximum number of DMA channels */ - nveu32_t max_chans; -}; - -/** - * @brief eqos_init_dma_chan_ops - Initialize eqos DMA operations. - * - * @param[in] ops: DMA channel operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void eqos_init_dma_chan_ops(struct dma_chan_ops *ops); - -/** - * @brief mgbe_init_dma_chan_ops - Initialize MGBE DMA operations. - * - * @param[in] ops: DMA channel operations pointer. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops); - -/** - * @brief eqos_get_desc_ops - EQOS init DMA descriptor operations - */ -void eqos_init_desc_ops(struct desc_ops *d_ops); - -/** - * @brief mgbe_get_desc_ops - MGBE init DMA descriptor operations - */ -void mgbe_init_desc_ops(struct desc_ops *d_ops); - -nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma); - -/** - * @brief osi_hw_transmit - Initialize Tx DMA descriptors for a channel - * - * @note - * Algorithm: - * - Initialize Transmit descriptors with DMA mappable buffers, - * set OWN bit, Tx ring length and set starting address of Tx DMA channel - * Tx ring base address in Tx DMA registers. - * - * @param[in, out] osi_dma: OSI DMA private data. - * @param[in] tx_ring: DMA Tx ring. - * @param[in] ops: DMA channel operations. - * @param[in] chan: DMA Tx channel number. Max OSI_EQOS_MAX_NUM_CHANS. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, - struct osi_tx_ring *tx_ring, - struct dma_chan_ops *ops, - nveu32_t chan); - -/* Function prototype needed for misra */ - -/** - * @brief dma_desc_init - Initialize DMA Tx/Rx descriptors - * - * @note - * Algorithm: - * - Transmit and Receive descriptors will be initialized with - * required values so that MAC DMA can understand and act accordingly. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * @param[in] ops: DMA channel operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops); - -static inline nveu32_t is_power_of_two(nveu32_t num) -{ - if ((num > 0U) && ((num & (num - 1U)) == 0U)) { - return OSI_ENABLE; - } - - return OSI_DISABLE; -} - -/** - * @addtogroup Helper Helper MACROS - * - * @brief EQOS generic helper MACROS. - * @{ - */ -#define CHECK_CHAN_BOUND(chan) \ - { \ - if ((chan) >= OSI_EQOS_MAX_NUM_CHANS) { \ - return; \ - } \ - } - -#define MGBE_CHECK_CHAN_BOUND(chan) \ -{ \ - if ((chan) >= OSI_MGBE_MAX_NUM_CHANS) { \ - return; \ - } \ -} \ - -#define BOOLEAN_FALSE (0U != 0U) -#define L32(data) ((nveu32_t)((data) & 0xFFFFFFFFU)) -#define H32(data) ((nveu32_t)(((data) & 0xFFFFFFFF00000000UL) >> 32UL)) -/** @} */ - -#endif /* INCLUDED_DMA_LOCAL_H */ diff --git a/osi/dma/eqos_desc.c b/osi/dma/eqos_desc.c deleted file mode 100644 index f45b200..0000000 --- a/osi/dma/eqos_desc.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "dma_local.h" -#include "hw_desc.h" - -/** - * @brief eqos_get_rx_vlan - Get Rx VLAN from descriptor - * - * Algorithm: - * 1) Check if the descriptor has any type set. - * 2) If set, set a per packet context flag indicating packet is VLAN - * tagged. - * 3) Extract VLAN tag ID from the descriptor - * - * @param[in] rx_desc: Rx descriptor - * @param[in] rx_pkt_cx: Per-Rx packet context structure - */ -static inline void eqos_get_rx_vlan(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - unsigned int lt; - - /* Check for Receive Status rdes0 */ - if ((rx_desc->rdes3 & RDES3_RS0V) == RDES3_RS0V) { - /* get length or type */ - lt = rx_desc->rdes3 & RDES3_LT; - if (lt == RDES3_LT_VT || lt == RDES3_LT_DVT) { - rx_pkt_cx->flags |= OSI_PKT_CX_VLAN; - rx_pkt_cx->vlan_tag = rx_desc->rdes0 & RDES0_OVT; - } - } -} - -/** - * @brief eqos_update_rx_err_stats - Detect Errors from Rx Descriptor - * - * Algorithm: This routine will be invoked by OSI layer itself which - * checks for the Last Descriptor and updates the receive status errors - * accordingly. - * - * @param[in] rx_desc: Rx Descriptor. - * @param[in] pkt_err_stats: Packet error stats which stores the errors reported - */ -static inline void eqos_update_rx_err_stats(struct osi_rx_desc *rx_desc, - struct osi_pkt_err_stats *stats) -{ - /* increment rx crc if we see CE bit set */ - if ((rx_desc->rdes3 & RDES3_ERR_CRC) == RDES3_ERR_CRC) { - stats->rx_crc_error = - osi_update_stats_counter(stats->rx_crc_error, 1UL); - } - - /* increment rx frame error if we see RE bit set */ - if ((rx_desc->rdes3 & RDES3_ERR_RE) == RDES3_ERR_RE) { - stats->rx_frame_error = - osi_update_stats_counter(stats->rx_frame_error, 1UL); - } -} - -/** - * @brief eqos_get_rx_csum - Get the Rx checksum from descriptor if valid - * - * @note - * Algorithm: - * - Check if the descriptor has any checksum validation errors. - * - If none, set a per packet context flag indicating no err in - * Rx checksum - * - The OSD layer will mark the packet appropriately to skip - * IP/TCP/UDP checksum validation in software based on whether - * COE is enabled for the device. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in, out] rx_desc: Rx descriptor - * @param[in, out] rx_pkt_cx: Per-Rx packet context structure - */ -static void eqos_get_rx_csum(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - nveu32_t pkt_type; - - /* Set rxcsum flags based on RDES1 values. These are required - * for QNX as it requires more granularity. - * Set none/unnecessary bit as well for other OS to check and - * take proper actions. - */ - if ((rx_desc->rdes3 & RDES3_RS1V) != RDES3_RS1V) { - return; - } - - if ((rx_desc->rdes1 & - (RDES1_IPCE | RDES1_IPCB | RDES1_IPHE)) == OSI_DISABLE) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; - } - - if ((rx_desc->rdes1 & RDES1_IPCB) != OSI_DISABLE) { - return; - } - - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_IPv4; - if ((rx_desc->rdes1 & RDES1_IPHE) == RDES1_IPHE) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_IPv4_BAD; - } - - pkt_type = rx_desc->rdes1 & RDES1_PT_MASK; - if ((rx_desc->rdes1 & RDES1_IPV4) == RDES1_IPV4) { - if (pkt_type == RDES1_PT_UDP) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv4; - } else if (pkt_type == RDES1_PT_TCP) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv4; - - } else { - /* Do nothing */ - } - } else if ((rx_desc->rdes1 & RDES1_IPV6) == RDES1_IPV6) { - if (pkt_type == RDES1_PT_UDP) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UDPv6; - } else if (pkt_type == RDES1_PT_TCP) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCPv6; - - } else { - /* Do nothing */ - } - - } else { - /* Do nothing */ - } - - if ((rx_desc->rdes1 & RDES1_IPCE) == RDES1_IPCE) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_TCP_UDP_BAD; - } -} - -/** - * @brief eqos_get_rx_hash - Get Rx packet hash from descriptor if valid - * - * Algorithm: This routine will be invoked by OSI layer itself to get received - * packet Hash from descriptor if RSS hash is valid and it also sets the type - * of RSS hash. - * - * @param[in] rx_desc: Rx Descriptor. - * @param[in] rx_pkt_cx: Per-Rx packet context structure - */ -static void eqos_get_rx_hash(OSI_UNUSED struct osi_rx_desc *rx_desc, - OSI_UNUSED struct osi_rx_pkt_cx *rx_pkt_cx) -{ -} - -/** - * @brief eqos_get_rx_hwstamp - Get Rx HW Time stamp - * - * Algorithm: - * 1) Check for TS availability. - * 2) call get_tx_tstamp_status if TS is valid or not. - * 3) If yes, set a bit and update nano seconds in rx_pkt_cx so that OSD - * layer can extract the time by checking this bit. - * - * @param[in] rx_desc: Rx descriptor - * @param[in] context_desc: Rx context descriptor - * @param[in] rx_pkt_cx: Rx packet context - * - * @retval -1 if TimeStamp is not available - * @retval 0 if TimeStamp is available. - */ -static int eqos_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, - struct osi_rx_desc *rx_desc, - struct osi_rx_desc *context_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - int retry; - - /* Check for RS1V/TSA/TD valid */ - if (((rx_desc->rdes3 & RDES3_RS1V) == RDES3_RS1V) && - ((rx_desc->rdes1 & RDES1_TSA) == RDES1_TSA) && - ((rx_desc->rdes1 & RDES1_TD) == 0U)) { - for (retry = 0; retry < 10; retry++) { - if (((context_desc->rdes3 & RDES3_OWN) == 0U) && - ((context_desc->rdes3 & RDES3_CTXT) == - RDES3_CTXT)) { - if ((context_desc->rdes0 == - OSI_INVALID_VALUE) && - (context_desc->rdes1 == - OSI_INVALID_VALUE)) { - return -1; - } - /* Update rx pkt context flags to indicate - * PTP */ - rx_pkt_cx->flags |= OSI_PKT_CX_PTP; - /* Time Stamp can be read */ - break; - } else { - /* TS not available yet, so retrying */ - osi_dma->osd_ops.udelay(OSI_DELAY_1US); - } - } - if (retry == 10) { - /* Timed out waiting for Rx timestamp */ - return -1; - } - - rx_pkt_cx->ns = context_desc->rdes0 + - (OSI_NSEC_PER_SEC * context_desc->rdes1); - if (rx_pkt_cx->ns < context_desc->rdes0) { - /* Will not hit this case */ - return -1; - } - } else { - return -1; - } - - return 0; -} - -void eqos_init_desc_ops(struct desc_ops *d_ops) -{ - d_ops->get_rx_csum = eqos_get_rx_csum; - d_ops->update_rx_err_stats = eqos_update_rx_err_stats; - d_ops->get_rx_vlan = eqos_get_rx_vlan; - d_ops->get_rx_hash = eqos_get_rx_hash; - d_ops->get_rx_hwstamp = eqos_get_rx_hwstamp; -} diff --git a/osi/dma/eqos_dma.c b/osi/dma/eqos_dma.c deleted file mode 100644 index 095ddbf..0000000 --- a/osi/dma/eqos_dma.c +++ /dev/null @@ -1,988 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 "../osi/common/common.h" -#include "dma_local.h" -#include "eqos_dma.h" -#include "../osi/common/type.h" - -/** - * @brief eqos_dma_safety_config - EQOS MAC DMA safety configuration - */ -static struct dma_func_safety eqos_dma_safety_config; - -/** - * @brief Write to safety critical register. - * - * @note - * Algorithm: - * - Acquire RW lock, so that eqos_validate_dma_regs does not run while - * updating the safety critical register. - * - call osi_writel() to actually update the memory mapped register. - * - Store the same value in eqos_dma_safety_config->reg_val[idx], so that - * this latest value will be compared when eqos_validate_dma_regs is - * scheduled. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] val: Value to be written. - * @param[in] addr: memory mapped register address to be written to. - * @param[in] idx: Index of register corresponding to enum func_safety_dma_regs. - * - * @pre MAC has to be out of reset, and clocks supplied. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - */ -static inline void eqos_dma_safety_writel(struct osi_dma_priv_data *osi_dma, - nveu32_t val, void *addr, - nveu32_t idx) -{ - struct dma_func_safety *config = &eqos_dma_safety_config; - - osi_lock_irq_enabled(&config->dma_safety_lock); - osi_writela(osi_dma->osd, val, addr); - config->reg_val[idx] = (val & config->reg_mask[idx]); - osi_unlock_irq_enabled(&config->dma_safety_lock); -} - -/** - * @brief Initialize the eqos_dma_safety_config. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note - * Algorithm: - * - Populate the list of safety critical registers and provide - * - the address of the register - * - Register mask (to ignore reserved/self-critical bits in the reg). - * See eqos_validate_dma_regs which can be invoked periodically to compare - * the last written value to this register vs the actual value read when - * eqos_validate_dma_regs is scheduled. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_dma_safety_init(struct osi_dma_priv_data *osi_dma) -{ - struct dma_func_safety *config = &eqos_dma_safety_config; - nveu8_t *base = (nveu8_t *)osi_dma->base; - nveu32_t val; - nveu32_t i, idx; - - /* Initialize all reg address to NULL, since we may not use - * some regs depending on the number of DMA chans enabled. - */ - for (i = EQOS_DMA_CH0_CTRL_IDX; i < EQOS_MAX_DMA_SAFETY_REGS; i++) { - config->reg_addr[i] = OSI_NULL; - } - - for (i = 0U; i < osi_dma->num_dma_chans; i++) { - idx = osi_dma->dma_chans[i]; -#if 0 - CHECK_CHAN_BOUND(idx); -#endif - config->reg_addr[EQOS_DMA_CH0_CTRL_IDX + idx] = base + - EQOS_DMA_CHX_CTRL(idx); - config->reg_addr[EQOS_DMA_CH0_TX_CTRL_IDX + idx] = base + - EQOS_DMA_CHX_TX_CTRL(idx); - config->reg_addr[EQOS_DMA_CH0_RX_CTRL_IDX + idx] = base + - EQOS_DMA_CHX_RX_CTRL(idx); - config->reg_addr[EQOS_DMA_CH0_TDRL_IDX + idx] = base + - EQOS_DMA_CHX_TDRL(idx); - config->reg_addr[EQOS_DMA_CH0_RDRL_IDX + idx] = base + - EQOS_DMA_CHX_RDRL(idx); - config->reg_addr[EQOS_DMA_CH0_INTR_ENA_IDX + idx] = base + - EQOS_DMA_CHX_INTR_ENA(idx); - - config->reg_mask[EQOS_DMA_CH0_CTRL_IDX + idx] = - EQOS_DMA_CHX_CTRL_MASK; - config->reg_mask[EQOS_DMA_CH0_TX_CTRL_IDX + idx] = - EQOS_DMA_CHX_TX_CTRL_MASK; - config->reg_mask[EQOS_DMA_CH0_RX_CTRL_IDX + idx] = - EQOS_DMA_CHX_RX_CTRL_MASK; - config->reg_mask[EQOS_DMA_CH0_TDRL_IDX + idx] = - EQOS_DMA_CHX_TDRL_MASK; - config->reg_mask[EQOS_DMA_CH0_RDRL_IDX + idx] = - EQOS_DMA_CHX_RDRL_MASK; - config->reg_mask[EQOS_DMA_CH0_INTR_ENA_IDX + idx] = - EQOS_DMA_CHX_INTR_ENA_MASK; - } - - /* Initialize current power-on-reset values of these registers. */ - for (i = EQOS_DMA_CH0_CTRL_IDX; i < EQOS_MAX_DMA_SAFETY_REGS; i++) { - if (config->reg_addr[i] == OSI_NULL) { - continue; - } - val = osi_readl((nveu8_t *)config->reg_addr[i]); - config->reg_val[i] = val & config->reg_mask[i]; - } - - osi_lock_init(&config->dma_safety_lock); -} - -/** - * @brief eqos_disable_chan_tx_intr - Disables DMA Tx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes - */ -static void eqos_disable_chan_tx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl, status; - -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - /* Clear irq before disabling */ - status = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - if ((status & EQOS_VIRT_INTR_CHX_STATUS_TX) == - EQOS_VIRT_INTR_CHX_STATUS_TX) { - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, - (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - } - - /* Disable the irq */ - cntrl = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); - cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief eqos_enable_chan_tx_intr - Enable Tx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_enable_chan_tx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); - cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief eqos_disable_chan_rx_intr - Disable Rx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: Yes - */ -static void eqos_disable_chan_rx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl, status; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - /* Clear irq before disabling */ - status = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - if ((status & EQOS_VIRT_INTR_CHX_STATUS_RX) == - EQOS_VIRT_INTR_CHX_STATUS_RX) { - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, - (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_STATUS(chan)); - } - - /* Disable irq */ - cntrl = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); - cntrl &= ~EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief eqos_enable_chan_rx_intr - Enable Rx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_enable_chan_rx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); - cntrl |= EQOS_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (nveu8_t *)addr + - EQOS_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief eqos_set_tx_ring_len - Set DMA Tx ring length. - * - * @note - * Algorithm: - * - Set DMA Tx channel ring length for specific channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Tx channel number. - * @param[in] len: Length. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_set_tx_ring_len(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len) -{ - void *addr = osi_dma->base; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - eqos_dma_safety_writel(osi_dma, len, (nveu8_t *)addr + - EQOS_DMA_CHX_TDRL(chan), - EQOS_DMA_CH0_TDRL_IDX + chan); -} - -/** - * @brief eqos_set_tx_ring_start_addr - Set DMA Tx ring base address. - * - * @note - * Algorithm: - * - Sets DMA Tx ring base address for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * @param[in] tx_desc: Tx desc base address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_set_tx_ring_start_addr(void *addr, nveu32_t chan, - nveu64_t tx_desc) -{ - nveu64_t tmp; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - tmp = H32(tx_desc); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_TDLH(chan)); - } - - tmp = L32(tx_desc); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_TDLA(chan)); - } -} - -/** - * @brief eqos_update_tx_tailptr - Updates DMA Tx ring tail pointer. - * - * @note - * Algorithm: - * - Updates DMA Tx ring tail pointer for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * @param[in] tailptr: DMA Tx ring tail pointer. - * - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_update_tx_tailptr(void *addr, nveu32_t chan, - nveu64_t tailptr) -{ - nveu64_t tmp; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - tmp = L32(tailptr); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_TDTP(chan)); - } -} - -/** - * @brief eqos_set_rx_ring_len - Set Rx channel ring length. - * - * @note - * Algorithm: - * - Sets DMA Rx channel ring length for specific DMA channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Rx channel number. - * @param[in] len: Length - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_set_rx_ring_len(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len) -{ - void *addr = osi_dma->base; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - eqos_dma_safety_writel(osi_dma, len, (nveu8_t *)addr + - EQOS_DMA_CHX_RDRL(chan), - EQOS_DMA_CH0_RDRL_IDX + chan); -} - -/** - * @brief eqos_set_rx_ring_start_addr - Set DMA Rx ring base address. - * - * @note - * Algorithm: - * - Sets DMA Rx channel ring base address. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * @param[in] rx_desc: DMA Rx desc base address. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_set_rx_ring_start_addr(void *addr, nveu32_t chan, - nveu64_t rx_desc) -{ - nveu64_t tmp; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - tmp = H32(rx_desc); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_RDLH(chan)); - } - - tmp = L32(rx_desc); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_RDLA(chan)); - } -} - -/** - * @brief eqos_update_rx_tailptr - Update Rx ring tail pointer - * - * @note - * Algorithm: - * - Updates DMA Rx channel tail pointer for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * @param[in] tailptr: Tail pointer - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_update_rx_tailptr(void *addr, nveu32_t chan, - nveu64_t tailptr) -{ - nveu64_t tmp; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - tmp = L32(tailptr); - if (tmp < UINT_MAX) { - osi_writel((nveu32_t)tmp, (nveu8_t *)addr + - EQOS_DMA_CHX_RDTP(chan)); - } -} - -/** - * @brief eqos_start_dma - Start DMA. - * - * @note - * Algorithm: - * - Start Tx and Rx DMA for specific channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Tx/Rx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - nveu32_t val; - void *addr = osi_dma->base; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - /* start Tx DMA */ - val = osi_readla(osi_dma->osd, - (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); - val |= OSI_BIT(0); - eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + - EQOS_DMA_CHX_TX_CTRL(chan), - EQOS_DMA_CH0_TX_CTRL_IDX + chan); - - /* start Rx DMA */ - val = osi_readla(osi_dma->osd, - (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); - val |= OSI_BIT(0); - val &= ~OSI_BIT(31); - eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + - EQOS_DMA_CHX_RX_CTRL(chan), - EQOS_DMA_CH0_RX_CTRL_IDX + chan); -} - -/** - * @brief eqos_stop_dma - Stop DMA. - * - * @note - * Algorithm: - * - Start Tx and Rx DMA for specific channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Tx/Rx channel number. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - * @note - * API Group: - * - Initialization: No - * - Run time: No - * - De-initialization: Yes - */ -static void eqos_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - nveu32_t val; - void *addr = osi_dma->base; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - /* stop Tx DMA */ - val = osi_readla(osi_dma->osd, - (nveu8_t *)addr + EQOS_DMA_CHX_TX_CTRL(chan)); - val &= ~OSI_BIT(0); - eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + - EQOS_DMA_CHX_TX_CTRL(chan), - EQOS_DMA_CH0_TX_CTRL_IDX + chan); - - /* stop Rx DMA */ - val = osi_readla(osi_dma->osd, - (nveu8_t *)addr + EQOS_DMA_CHX_RX_CTRL(chan)); - val &= ~OSI_BIT(0); - val |= OSI_BIT(31); - eqos_dma_safety_writel(osi_dma, val, (nveu8_t *)addr + - EQOS_DMA_CHX_RX_CTRL(chan), - EQOS_DMA_CH0_RX_CTRL_IDX + chan); -} - -/** - * @brief eqos_configure_dma_channel - Configure DMA channel - * - * @note - * Algorithm: - * - This takes care of configuring the below - * parameters for the DMA channel - * - Enabling DMA channel interrupts - * - Enable 8xPBL mode - * - Program Tx, Rx PBL - * - Enable TSO if HW supports - * - Program Rx Watchdog timer - * - * @param[in] chan: DMA channel number that need to be configured. - * @param[in] osi_dma: OSI DMA private data structure. - * - * @pre MAC has to be out of reset. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - */ -static void eqos_configure_dma_channel(nveu32_t chan, - struct osi_dma_priv_data *osi_dma) -{ - nveu32_t value; -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - /* enable DMA channel interrupts */ - /* Enable TIE and TBUE */ - /* TIE - Transmit Interrupt Enable */ - /* TBUE - Transmit Buffer Unavailable Enable */ - /* RIE - Receive Interrupt Enable */ - /* RBUE - Receive Buffer Unavailable Enable */ - /* AIE - Abnormal Interrupt Summary Enable */ - /* NIE - Normal Interrupt Summary Enable */ - /* FBE - Fatal Bus Error Enable */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_INTR_ENA(chan)); - if (osi_dma->use_virtualization == OSI_DISABLE) { - value |= EQOS_DMA_CHX_INTR_TBUE | - EQOS_DMA_CHX_INTR_RBUE; - } - - value |= EQOS_DMA_CHX_INTR_TIE | EQOS_DMA_CHX_INTR_RIE | - EQOS_DMA_CHX_INTR_FBEE | EQOS_DMA_CHX_INTR_AIE | - EQOS_DMA_CHX_INTR_NIE; - /* For multi-irqs to work nie needs to be disabled */ - value &= ~(EQOS_DMA_CHX_INTR_NIE); - eqos_dma_safety_writel(osi_dma, value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_INTR_ENA(chan), - EQOS_DMA_CH0_INTR_ENA_IDX + chan); - - /* Enable 8xPBL mode */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_CTRL(chan)); - value |= EQOS_DMA_CHX_CTRL_PBLX8; - eqos_dma_safety_writel(osi_dma, value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_CTRL(chan), - EQOS_DMA_CH0_CTRL_IDX + chan); - - /* Configure DMA channel Transmit control register */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_TX_CTRL(chan)); - /* Enable OSF mode */ - value |= EQOS_DMA_CHX_TX_CTRL_OSF; - /* TxPBL = 32*/ - value |= EQOS_DMA_CHX_TX_CTRL_TXPBL_RECOMMENDED; - /* enable TSO by default if HW supports */ - value |= EQOS_DMA_CHX_TX_CTRL_TSE; - - eqos_dma_safety_writel(osi_dma, value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_TX_CTRL(chan), - EQOS_DMA_CH0_TX_CTRL_IDX + chan); - - /* Configure DMA channel Receive control register */ - /* Select Rx Buffer size. Needs to be rounded up to next multiple of - * bus width - */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_RX_CTRL(chan)); - - /* clear previous Rx buffer size */ - value &= ~EQOS_DMA_CHX_RBSZ_MASK; - - value |= (osi_dma->rx_buf_len << EQOS_DMA_CHX_RBSZ_SHIFT); - /* RXPBL = 12 */ - value |= EQOS_DMA_CHX_RX_CTRL_RXPBL_RECOMMENDED; - eqos_dma_safety_writel(osi_dma, value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_RX_CTRL(chan), - EQOS_DMA_CH0_RX_CTRL_IDX + chan); - - /* Set Receive Interrupt Watchdog Timer Count */ - /* conversion of usec to RWIT value - * Eg: System clock is 125MHz, each clock cycle would then be 8ns - * For value 0x1 in RWT, device would wait for 512 clk cycles with - * RWTU as 0x1, - * ie, (8ns x 512) => 4.096us (rounding off to 4us) - * So formula with above values is,ret = usec/4 - */ - if ((osi_dma->use_riwt == OSI_ENABLE) && - (osi_dma->rx_riwt < UINT_MAX)) { - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_RX_WDT(chan)); - /* Mask the RWT and RWTU value */ - value &= ~(EQOS_DMA_CHX_RX_WDT_RWT_MASK | - EQOS_DMA_CHX_RX_WDT_RWTU_MASK); - /* Conversion of usec to Rx Interrupt Watchdog Timer Count */ - value |= ((osi_dma->rx_riwt * - (EQOS_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / - EQOS_DMA_CHX_RX_WDT_RWTU) & - EQOS_DMA_CHX_RX_WDT_RWT_MASK; - value |= EQOS_DMA_CHX_RX_WDT_RWTU_512_CYCLE; - osi_writel(value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_RX_WDT(chan)); - } -} - -/** - * @brief eqos_init_dma_channel - DMA channel INIT - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_init_dma_channel(struct osi_dma_priv_data *osi_dma) -{ - nveu32_t chinx; - - eqos_dma_safety_init(osi_dma); - - /* configure EQOS DMA channels */ - for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { - eqos_configure_dma_channel(osi_dma->dma_chans[chinx], osi_dma); - } - - return 0; -} - -/** - * @brief eqos_set_rx_buf_len - Set Rx buffer length - * Sets the Rx buffer length based on the new MTU size set. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC needs to be out of reset and proper clocks need to be configured - * - DMA HW init need to be completed successfully, see osi_hw_dma_init - * - osi_dma->mtu need to be filled with current MTU size <= 9K - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) -{ - nveu32_t rx_buf_len = 0U; - - /* Add Ethernet header + VLAN header + NET IP align size to MTU */ - if (osi_dma->mtu <= OSI_MAX_MTU_SIZE) { - rx_buf_len = osi_dma->mtu + OSI_ETH_HLEN + NV_VLAN_HLEN + - OSI_NET_IP_ALIGN; - } else { - rx_buf_len = OSI_MAX_MTU_SIZE + OSI_ETH_HLEN + NV_VLAN_HLEN + - OSI_NET_IP_ALIGN; - } - - /* Buffer alignment */ - osi_dma->rx_buf_len = ((rx_buf_len + (EQOS_AXI_BUS_WIDTH - 1U)) & - ~(EQOS_AXI_BUS_WIDTH - 1U)); -} - -#ifndef OSI_STRIPPED_LIB -/** - * @brief Read-validate HW registers for functional safety. - * - * @note - * Algorithm: - * - Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC has to be out of reset. - * - osi_hw_dma_init has to be called. Internally this would initialize - * the safety_config (see osi_dma_priv_data) based on MAC version and - * which specific registers needs to be validated periodically. - * - Invoke this call if (osi_dma_priv_data->safety_config != OSI_NULL) - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t eqos_validate_dma_regs(struct osi_dma_priv_data *osi_dma) -{ - struct dma_func_safety *config = - (struct dma_func_safety *)osi_dma->safety_config; - nveu32_t cur_val; - nveu32_t i; - - osi_lock_irq_enabled(&config->dma_safety_lock); - for (i = EQOS_DMA_CH0_CTRL_IDX; i < EQOS_MAX_DMA_SAFETY_REGS; i++) { - if (config->reg_addr[i] == OSI_NULL) { - continue; - } - - cur_val = osi_readl((nveu8_t *)config->reg_addr[i]); - cur_val &= config->reg_mask[i]; - - if (cur_val == config->reg_val[i]) { - continue; - } else { - /* Register content differs from what was written. - * Return error and let safety manager (NVGaurd etc.) - * take care of corrective action. - */ - osi_unlock_irq_enabled(&config->dma_safety_lock); - return -1; - } - } - osi_unlock_irq_enabled(&config->dma_safety_lock); - - return 0; -} - -/** - * @brief eqos_config_slot - Configure slot Checking for DMA channel - * - * @note - * Algorithm: - * - Set/Reset the slot function of DMA channel based on given inputs - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA channel number to enable slot function - * @param[in] set: flag for set/reset with value OSI_ENABLE/OSI_DISABLE - * @param[in] interval: slot interval from 0usec to 4095usec - * - * @pre - * - MAC should be init and started. see osi_start_mac() - * - OSD should be initialized - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: No - */ -static void eqos_config_slot(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t set, - nveu32_t interval) -{ - nveu32_t value; - nveu32_t intr; - -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - if (set == OSI_ENABLE) { - /* Program SLOT CTRL register SIV and set ESC bit */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - value &= ~EQOS_DMA_CHX_SLOT_SIV_MASK; - /* remove overflow bits of interval */ - intr = interval & EQOS_DMA_CHX_SLOT_SIV_MASK; - value |= (intr << EQOS_DMA_CHX_SLOT_SIV_SHIFT); - /* Set ESC bit */ - value |= EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - - } else { - /* Clear ESC bit of SLOT CTRL register */ - value = osi_readl((nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - value &= ~EQOS_DMA_CHX_SLOT_ESC; - osi_writel(value, (nveu8_t *)osi_dma->base + - EQOS_DMA_CHX_SLOT_CTRL(chan)); - } -} -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief eqos_clear_vm_tx_intr - Handle VM Tx interrupt - * - * @param[in] addr: MAC base address. - * @param[in] chan: DMA Tx channel number. - * - * Algorithm: Clear Tx interrupt source at DMA and wrapper level. - * - * @note - * Dependencies: None. - * Protection: None. - * @retval None. - */ -static void eqos_clear_vm_tx_intr(void *addr, nveu32_t chan) -{ -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_TX, - (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_TX, - (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); - - eqos_disable_chan_tx_intr(addr, chan); -} - -/** - * @brief eqos_clear_vm_rx_intr - Handle VM Rx interrupt - * - * @param[in] addr: MAC base address. - * @param[in] chan: DMA Rx channel number. - * - * Algorithm: Clear Rx interrupt source at DMA and wrapper level. - * - * @note - * Dependencies: None. - * Protection: None. - * - * @retval None. - */ -static void eqos_clear_vm_rx_intr(void *addr, nveu32_t chan) -{ -#if 0 - CHECK_CHAN_BOUND(chan); -#endif - osi_writel(EQOS_DMA_CHX_STATUS_CLEAR_RX, - (nveu8_t *)addr + EQOS_DMA_CHX_STATUS(chan)); - osi_writel(EQOS_VIRT_INTR_CHX_STATUS_RX, - (nveu8_t *)addr + EQOS_VIRT_INTR_CHX_STATUS(chan)); - - eqos_disable_chan_rx_intr(addr, chan); -} - -/** - * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration - */ -void *eqos_get_dma_safety_config(void) -{ - return &eqos_dma_safety_config; -} - -/** - * @brief eqos_init_dma_chan_ops - Initialize EQOS DMA operations. - * - * @param[in] ops: DMA channel operations pointer. - */ -void eqos_init_dma_chan_ops(struct dma_chan_ops *ops) -{ - ops->set_tx_ring_len = eqos_set_tx_ring_len; - ops->set_rx_ring_len = eqos_set_rx_ring_len; - ops->set_tx_ring_start_addr = eqos_set_tx_ring_start_addr; - ops->set_rx_ring_start_addr = eqos_set_rx_ring_start_addr; - ops->update_tx_tailptr = eqos_update_tx_tailptr; - ops->update_rx_tailptr = eqos_update_rx_tailptr; - ops->disable_chan_tx_intr = eqos_disable_chan_tx_intr; - ops->enable_chan_tx_intr = eqos_enable_chan_tx_intr; - ops->disable_chan_rx_intr = eqos_disable_chan_rx_intr; - ops->enable_chan_rx_intr = eqos_enable_chan_rx_intr; - ops->start_dma = eqos_start_dma; - ops->stop_dma = eqos_stop_dma; - ops->init_dma_channel = eqos_init_dma_channel; - ops->set_rx_buf_len = eqos_set_rx_buf_len; -#ifndef OSI_STRIPPED_LIB - ops->validate_regs = eqos_validate_dma_regs; - ops->config_slot = eqos_config_slot; -#endif /* !OSI_STRIPPED_LIB */ - ops->clear_vm_tx_intr = eqos_clear_vm_tx_intr; - ops->clear_vm_rx_intr = eqos_clear_vm_rx_intr; -} diff --git a/osi/dma/eqos_dma.h b/osi/dma/eqos_dma.h deleted file mode 100644 index 7644438..0000000 --- a/osi/dma/eqos_dma.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 INCLUDED_EQOS_DMA_H -#define INCLUDED_EQOS_DMA_H - -/** - * @addtogroup EQOS AXI Clock defines - * - * @brief AXI Clock defines - * @{ - */ -#define EQOS_AXI_CLK_FREQ 125000000U -/** @} */ - -/** - * @addtogroup EQOS1 DMA Channel Register offsets - * - * @brief EQOS DMA Channel register offsets - * @{ - */ -#define EQOS_DMA_CHX_CTRL(x) ((0x0080U * (x)) + 0x1100U) -#define EQOS_DMA_CHX_TX_CTRL(x) ((0x0080U * (x)) + 0x1104U) -#define EQOS_DMA_CHX_RX_CTRL(x) ((0x0080U * (x)) + 0x1108U) -#define EQOS_DMA_CHX_INTR_ENA(x) ((0x0080U * (x)) + 0x1134U) -#define EQOS_DMA_CHX_RX_WDT(x) ((0x0080U * (x)) + 0x1138U) -#ifndef OSI_STRIPPED_LIB -#define EQOS_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x113CU) -#endif /* !OSI_STRIPPED_LIB */ - -#define EQOS_DMA_CHX_RDTP(x) ((0x0080U * (x)) + 0x1128U) -#define EQOS_DMA_CHX_RDLH(x) ((0x0080U * (x)) + 0x1118U) -#define EQOS_DMA_CHX_RDLA(x) ((0x0080U * (x)) + 0x111CU) -#define EQOS_DMA_CHX_RDRL(x) ((0x0080U * (x)) + 0x1130U) -#define EQOS_DMA_CHX_TDTP(x) ((0x0080U * (x)) + 0x1120U) -#define EQOS_DMA_CHX_TDLH(x) ((0x0080U * (x)) + 0x1110U) -#define EQOS_DMA_CHX_TDLA(x) ((0x0080U * (x)) + 0x1114U) -#define EQOS_DMA_CHX_TDRL(x) ((0x0080U * (x)) + 0x112CU) -#define EQOS_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) -#define EQOS_VIRT_INTR_CHX_STATUS(x) (0x8604U + ((x) * 8U)) -#define EQOS_VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) -/** @} */ - -/** - * @addtogroup EQOS2 BIT fields for EQOS MAC HW DMA Channel Registers - * - * @brief Values defined for the DMA channel registers - * @{ - */ -#define EQOS_VIRT_INTR_CHX_STATUS_TX OSI_BIT(0) -#define EQOS_VIRT_INTR_CHX_STATUS_RX OSI_BIT(1) -#define EQOS_DMA_CHX_STATUS_TI OSI_BIT(0) -#define EQOS_DMA_CHX_STATUS_RI OSI_BIT(6) -#define EQOS_DMA_CHX_STATUS_NIS OSI_BIT(15) -#define EQOS_DMA_CHX_STATUS_CLEAR_TX \ - (EQOS_DMA_CHX_STATUS_TI | EQOS_DMA_CHX_STATUS_NIS) -#define EQOS_DMA_CHX_STATUS_CLEAR_RX \ - (EQOS_DMA_CHX_STATUS_RI | EQOS_DMA_CHX_STATUS_NIS) - -#define EQOS_VIRT_INTR_CHX_CNTRL_TX OSI_BIT(0) -#define EQOS_VIRT_INTR_CHX_CNTRL_RX OSI_BIT(1) - -#define EQOS_DMA_CHX_INTR_TIE OSI_BIT(0) -#define EQOS_DMA_CHX_INTR_TBUE OSI_BIT(2) -#define EQOS_DMA_CHX_INTR_RIE OSI_BIT(6) -#define EQOS_DMA_CHX_INTR_RBUE OSI_BIT(7) -#define EQOS_DMA_CHX_INTR_FBEE OSI_BIT(12) -#define EQOS_DMA_CHX_INTR_AIE OSI_BIT(14) -#define EQOS_DMA_CHX_INTR_NIE OSI_BIT(15) -#define EQOS_DMA_CHX_TX_CTRL_OSF OSI_BIT(4) -#define EQOS_DMA_CHX_TX_CTRL_TSE OSI_BIT(12) -#define EQOS_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) -#define EQOS_DMA_CHX_RBSZ_MASK 0x7FFEU -#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 -#define EQOS_DMA_CHX_RX_WDT_RWT_MASK 0xFFU -#define EQOS_DMA_CHX_RX_WDT_RWTU_MASK 0x30000U -#define EQOS_DMA_CHX_RX_WDT_RWTU_512_CYCLE 0x10000U -#define EQOS_DMA_CHX_RX_WDT_RWTU 512U - -/* Below macros are used for periodic reg validation for functional safety. - * HW register mask - to mask out reserved and self-clearing bits - */ -#define EQOS_DMA_CHX_CTRL_MASK 0x11D3FFFU -#define EQOS_DMA_CHX_TX_CTRL_MASK 0xF3F9010U -#define EQOS_DMA_CHX_RX_CTRL_MASK 0x8F3F7FE0U -#define EQOS_DMA_CHX_TDRL_MASK 0x3FFU -#define EQOS_DMA_CHX_RDRL_MASK 0x3FFU -#define EQOS_DMA_CHX_INTR_ENA_MASK 0xFFC7U -#ifndef OSI_STRIPPED_LIB -#define EQOS_DMA_CHX_SLOT_SIV_MASK 0xFFFU -#define EQOS_DMA_CHX_SLOT_SIV_SHIFT 4U -#define EQOS_DMA_CHX_SLOT_ESC 0x1U -#endif /* !OSI_STRIPPED_LIB */ -/* To add new registers to validate,append at end of below macro list and - * increment EQOS_MAX_DMA_SAFETY_REGS. - * Using macros instead of enum due to misra error. - */ -#define EQOS_DMA_CH0_CTRL_IDX 0U -#define EQOS_DMA_CH1_CTRL_IDX 1U -#define EQOS_DMA_CH2_CTRL_IDX 2U -#define EQOS_DMA_CH3_CTRL_IDX 3U -#define EQOS_DMA_CH4_CTRL_IDX 4U -#define EQOS_DMA_CH5_CTRL_IDX 5U -#define EQOS_DMA_CH6_CTRL_IDX 6U -#define EQOS_DMA_CH7_CTRL_IDX 7U -#define EQOS_DMA_CH0_TX_CTRL_IDX 8U -#define EQOS_DMA_CH1_TX_CTRL_IDX 9U -#define EQOS_DMA_CH2_TX_CTRL_IDX 10U -#define EQOS_DMA_CH3_TX_CTRL_IDX 11U -#define EQOS_DMA_CH4_TX_CTRL_IDX 12U -#define EQOS_DMA_CH5_TX_CTRL_IDX 13U -#define EQOS_DMA_CH6_TX_CTRL_IDX 14U -#define EQOS_DMA_CH7_TX_CTRL_IDX 15U -#define EQOS_DMA_CH0_RX_CTRL_IDX 16U -#define EQOS_DMA_CH1_RX_CTRL_IDX 17U -#define EQOS_DMA_CH2_RX_CTRL_IDX 18U -#define EQOS_DMA_CH3_RX_CTRL_IDX 19U -#define EQOS_DMA_CH4_RX_CTRL_IDX 20U -#define EQOS_DMA_CH5_RX_CTRL_IDX 21U -#define EQOS_DMA_CH6_RX_CTRL_IDX 22U -#define EQOS_DMA_CH7_RX_CTRL_IDX 23U -#define EQOS_DMA_CH0_TDRL_IDX 24U -#define EQOS_DMA_CH1_TDRL_IDX 25U -#define EQOS_DMA_CH2_TDRL_IDX 26U -#define EQOS_DMA_CH3_TDRL_IDX 27U -#define EQOS_DMA_CH4_TDRL_IDX 28U -#define EQOS_DMA_CH5_TDRL_IDX 29U -#define EQOS_DMA_CH6_TDRL_IDX 30U -#define EQOS_DMA_CH7_TDRL_IDX 31U -#define EQOS_DMA_CH0_RDRL_IDX 32U -#define EQOS_DMA_CH1_RDRL_IDX 33U -#define EQOS_DMA_CH2_RDRL_IDX 34U -#define EQOS_DMA_CH3_RDRL_IDX 35U -#define EQOS_DMA_CH4_RDRL_IDX 36U -#define EQOS_DMA_CH5_RDRL_IDX 37U -#define EQOS_DMA_CH6_RDRL_IDX 38U -#define EQOS_DMA_CH7_RDRL_IDX 39U -#define EQOS_DMA_CH0_INTR_ENA_IDX 40U -#define EQOS_DMA_CH1_INTR_ENA_IDX 41U -#define EQOS_DMA_CH2_INTR_ENA_IDX 42U -#define EQOS_DMA_CH3_INTR_ENA_IDX 43U -#define EQOS_DMA_CH4_INTR_ENA_IDX 44U -#define EQOS_DMA_CH5_INTR_ENA_IDX 45U -#define EQOS_DMA_CH6_INTR_ENA_IDX 46U -#define EQOS_DMA_CH7_INTR_ENA_IDX 47U -#define EQOS_MAX_DMA_SAFETY_REGS 48U -#define EQOS_AXI_BUS_WIDTH 0x10U -/** @} */ - -/** - * @brief dma_func_safety - Struct used to store last written values of - * critical DMA HW registers. - */ -struct dma_func_safety { - /** Array of reg MMIO addresses (base EQoS + offset of reg) */ - void *reg_addr[EQOS_MAX_DMA_SAFETY_REGS]; - /** Array of bit-mask value of each corresponding reg - * (used to ignore self-clearing/reserved bits in reg) */ - nveu32_t reg_mask[EQOS_MAX_DMA_SAFETY_REGS]; - /** Array of value stored in each corresponding register */ - nveu32_t reg_val[EQOS_MAX_DMA_SAFETY_REGS]; - /** OSI lock variable used to protect writes to reg - * while validation is in-progress */ - nveu32_t dma_safety_lock; -}; - -/** - * @brief eqos_get_dma_safety_config - EQOS get DMA safety configuration - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @returns Pointer to DMA safety configuration - */ -void *eqos_get_dma_safety_config(void); -#endif /* INCLUDED_EQOS_DMA_H */ diff --git a/osi/dma/hw_common.h b/osi/dma/hw_common.h deleted file mode 100644 index a7b6335..0000000 --- a/osi/dma/hw_common.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022, 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 INCLUDED_HW_COMMON_H -#define INCLUDED_HW_COMMON_H - -/** - * @addtogroup COMMON HW specific offset macros - * - * @brief Register offset values common for EQOS and MGBE - * @{ - */ -#define HW_GLOBAL_DMA_STATUS 0x8700U -/** @} */ - -#endif /* INCLUDED_HW_COMMON_H */ - diff --git a/osi/dma/hw_desc.h b/osi/dma/hw_desc.h deleted file mode 100644 index 45cf896..0000000 --- a/osi/dma/hw_desc.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2018-2020, 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 INCLUDED_HW_DESC_H -#define INCLUDED_HW_DESC_H - -/** - * @addtogroup EQOS_RxDesc Receive Descriptors bit fields - * - * @brief These macros are used to check the value in specific bit fields of - * the descriptor. The fields in the descriptor are mapped as - * defined in the HW manual - * @{ - */ -#define RDES3_OWN OSI_BIT(31) -#define RDES3_CTXT OSI_BIT(30) -#define RDES3_IOC OSI_BIT(30) -#define RDES3_B1V OSI_BIT(24) -#define RDES3_CDA OSI_BIT(27) -#define RDES3_LD OSI_BIT(28) -#define RDES3_FD OSI_BIT(29) -#define RDES3_ERR_CRC OSI_BIT(24) -#define RDES3_ERR_GP OSI_BIT(23) -#define RDES3_ERR_WD OSI_BIT(22) -#define RDES3_ERR_ORUN OSI_BIT(21) -#define RDES3_ERR_RE OSI_BIT(20) -#define RDES3_ERR_DRIB OSI_BIT(19) -#define RDES3_PKT_LEN 0x00007fffU -#define RDES3_LT (OSI_BIT(16) | OSI_BIT(17) | OSI_BIT(18)) -#define RDES3_LT_VT OSI_BIT(18) -#define RDES3_LT_DVT (OSI_BIT(16) | OSI_BIT(18)) -#define RDES3_RS0V OSI_BIT(25) -#define RDES3_RS1V OSI_BIT(26) -#define RDES3_RSV OSI_BIT(26) -#define RDES0_OVT 0x0000FFFFU -#define RDES3_TSD OSI_BIT(6) -#define RDES3_TSA OSI_BIT(4) -#define RDES1_TSA OSI_BIT(14) -#define RDES1_TD OSI_BIT(15) -#define RDES3_L34T 0x00F00000U -#define RDES3_L34T_IPV4_TCP OSI_BIT(20) -#define RDES3_L34T_IPV4_UDP OSI_BIT(21) -#define RDES3_L34T_IPV6_TCP (OSI_BIT(23) | OSI_BIT(20)) -#define RDES3_L34T_IPV6_UDP (OSI_BIT(23) | OSI_BIT(21)) - -#define RDES1_IPCE OSI_BIT(7) -#define RDES1_IPCB OSI_BIT(6) -#define RDES1_IPV6 OSI_BIT(5) -#define RDES1_IPV4 OSI_BIT(4) -#define RDES1_IPHE OSI_BIT(3) -#define RDES1_PT_MASK (OSI_BIT(2) | OSI_BIT(1) | OSI_BIT(0)) -#define RDES1_PT_TCP OSI_BIT(1) -#define RDES1_PT_UDP OSI_BIT(0) -#define RDES3_ELLT 0xF0000U -#define RDES3_ELLT_IPHE 0x50000U -#define RDES3_ELLT_CSUM_ERR 0x60000U -#define RDES3_ELLT_CVLAN 0x90000U -/** @} */ - -/** Error Summary bits for Received packet */ -#define RDES3_ES_BITS \ - (RDES3_ERR_CRC | RDES3_ERR_GP | RDES3_ERR_WD | \ - RDES3_ERR_ORUN | RDES3_ERR_RE | RDES3_ERR_DRIB) - -/** MGBE error summary bits for Received packet */ -#define RDES3_ES_MGBE 0x8000U -#define RDES3_ERR_MGBE_CRC (OSI_BIT(16) | OSI_BIT(17)) -/** - * @addtogroup EQOS_TxDesc Transmit Descriptors bit fields - * - * @brief These macros are used to check the value in specific bit fields of - * the descriptor. The fields in the descriptor are mapped as - * defined in the HW manual - * @{ - */ -#define TDES2_IOC OSI_BIT(31) -#define TDES2_MSS_MASK 0x3FFFU -#define TDES3_OWN OSI_BIT(31) -#define TDES3_CTXT OSI_BIT(30) -#define TDES3_TCMSSV OSI_BIT(26) -#define TDES3_FD OSI_BIT(29) -#define TDES3_LD OSI_BIT(28) -#define TDES3_OSTC OSI_BIT(27) -#define TDES3_TSE OSI_BIT(18) -#define TDES3_HW_CIC_ALL (OSI_BIT(16) | OSI_BIT(17)) -#define TDES3_HW_CIC_IP_ONLY (OSI_BIT(16)) -#define TDES3_VT_MASK 0xFFFFU -#define TDES3_THL_MASK 0xFU -#define TDES3_TPL_MASK 0x3FFFFU -#define TDES3_PL_MASK 0x7FFFU -#define TDES3_THL_SHIFT 19U -#define TDES3_VLTV OSI_BIT(16) -#define TDES3_TTSS OSI_BIT(17) -#define TDES3_PIDV OSI_BIT(25) - -/* Tx Errors */ -#define TDES3_IP_HEADER_ERR OSI_BIT(0) -#define TDES3_UNDER_FLOW_ERR OSI_BIT(2) -#define TDES3_EXCESSIVE_DEF_ERR OSI_BIT(3) -#define TDES3_EXCESSIVE_COL_ERR OSI_BIT(8) -#define TDES3_LATE_COL_ERR OSI_BIT(9) -#define TDES3_NO_CARRIER_ERR OSI_BIT(10) -#define TDES3_LOSS_CARRIER_ERR OSI_BIT(11) -#define TDES3_PL_CHK_SUM_ERR OSI_BIT(12) -#define TDES3_PKT_FLUSH_ERR OSI_BIT(13) -#define TDES3_JABBER_TIMEO_ERR OSI_BIT(14) - -/* VTIR = 0x2 (Insert a VLAN tag with the tag value programmed in the - * MAC_VLAN_Incl register or context descriptor.) -*/ -#define TDES2_VTIR ((nveu32_t)0x2 << 14U) -#define TDES2_TTSE ((nveu32_t)0x1 << 30U) -/** @} */ - -/** Error Summary bits for Transmitted packet */ -#define TDES3_ES_BITS (TDES3_IP_HEADER_ERR | \ - TDES3_UNDER_FLOW_ERR | \ - TDES3_EXCESSIVE_DEF_ERR | \ - TDES3_EXCESSIVE_COL_ERR | \ - TDES3_LATE_COL_ERR | \ - TDES3_NO_CARRIER_ERR | \ - TDES3_LOSS_CARRIER_ERR | \ - TDES3_PL_CHK_SUM_ERR | \ - TDES3_PKT_FLUSH_ERR | \ - TDES3_JABBER_TIMEO_ERR) -#endif /* INCLUDED_HW_DESC_H */ diff --git a/osi/dma/libnvethernetcl.export b/osi/dma/libnvethernetcl.export deleted file mode 100644 index 311e3bc..0000000 --- a/osi/dma/libnvethernetcl.export +++ /dev/null @@ -1,42 +0,0 @@ -################################### tell Emacs this is a -*- makefile-gmake -*- -# -# Copyright (c) 2019-2022, 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. -# -# libnvethernetcl interface export -# -############################################################################### -osi_start_dma -osi_stop_dma -osi_get_refill_rx_desc_cnt -osi_rx_dma_desc_init -osi_set_rx_buf_len -osi_hw_transmit -osi_process_tx_completions -osi_process_rx_completions -osi_hw_dma_init -osi_hw_dma_deinit -osi_init_dma_ops -osi_dma_get_systime_from_mac -osi_is_mac_enabled -osi_get_dma -osi_handle_dma_intr -osi_get_global_dma_status -osi_dma_ioctl diff --git a/osi/dma/mgbe_desc.c b/osi/dma/mgbe_desc.c deleted file mode 100644 index ef12db5..0000000 --- a/osi/dma/mgbe_desc.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "dma_local.h" -#include "hw_desc.h" -#include "mgbe_desc.h" - -/** - * @brief mgbe_get_rx_vlan - Get Rx VLAN from descriptor - * - * Algorithm: - * 1) Check if the descriptor has CVLAN set - * 2) If set, set a per packet context flag indicating packet is VLAN - * tagged. - * 3) Extract VLAN tag ID from the descriptor - * - * @param[in] rx_desc: Rx descriptor - * @param[in] rx_pkt_cx: Per-Rx packet context structure - */ -static inline void mgbe_get_rx_vlan(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - unsigned int ellt = rx_desc->rdes3 & RDES3_ELLT; - - if ((ellt & RDES3_ELLT_CVLAN) == RDES3_ELLT_CVLAN) { - rx_pkt_cx->flags |= OSI_PKT_CX_VLAN; - rx_pkt_cx->vlan_tag = rx_desc->rdes0 & RDES0_OVT; - } -} - -/** - * @brief mgbe_get_rx_err_stats - Detect Errors from Rx Descriptor - * - * Algorithm: This routine will be invoked by OSI layer itself which - * checks for the Last Descriptor and updates the receive status errors - * accordingly. - * - * @param[in] rx_desc: Rx Descriptor. - * @param[in] pkt_err_stats: Packet error stats which stores the errors reported - */ -static inline void mgbe_update_rx_err_stats(struct osi_rx_desc *rx_desc, - struct osi_pkt_err_stats *stats) -{ - unsigned int frpsm = 0; - unsigned int frpsl = 0; - - /* increment rx crc if we see CE bit set */ - if ((rx_desc->rdes3 & RDES3_ERR_MGBE_CRC) == RDES3_ERR_MGBE_CRC) { - stats->rx_crc_error = - osi_update_stats_counter(stats->rx_crc_error, 1UL); - } - - /* Update FRP Counters */ - frpsm = rx_desc->rdes2 & MGBE_RDES2_FRPSM; - frpsl = rx_desc->rdes3 & MGBE_RDES3_FRPSL; - /* Increment FRP parsed count */ - if ((frpsm == OSI_NONE) && (frpsl == OSI_NONE)) { - stats->frp_parsed = - osi_update_stats_counter(stats->frp_parsed, 1UL); - } - /* Increment FRP dropped count */ - if ((frpsm == OSI_NONE) && (frpsl == MGBE_RDES3_FRPSL)) { - stats->frp_dropped = - osi_update_stats_counter(stats->frp_dropped, 1UL); - } - /* Increment FRP Parsing Error count */ - if ((frpsm == MGBE_RDES2_FRPSM) && (frpsl == OSI_NONE)) { - stats->frp_err = - osi_update_stats_counter(stats->frp_err, 1UL); - } - /* Increment FRP Incomplete Parsing count */ - if ((frpsm == MGBE_RDES2_FRPSM) && (frpsl == MGBE_RDES3_FRPSL)) { - stats->frp_incomplete = - osi_update_stats_counter(stats->frp_incomplete, 1UL); - } -} - -/** - * @brief mgbe_get_rx_csum - Get the Rx checksum from descriptor if valid - * - * Algorithm: - * 1) Check if the descriptor has any checksum validation errors. - * 2) If none, set a per packet context flag indicating no err in - * Rx checksum - * 3) The OSD layer will mark the packet appropriately to skip - * IP/TCP/UDP checksum validation in software based on whether - * COE is enabled for the device. - * - * @param[in] rx_desc: Rx descriptor - * @param[in] rx_pkt_cx: Per-Rx packet context structure - */ -static void mgbe_get_rx_csum(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - unsigned int ellt = rx_desc->rdes3 & RDES3_ELLT; - - /* Always include either checksum none/unnecessary - * depending on status fields in desc. - * Hence no need to explicitly add OSI_PKT_CX_CSUM flag. - */ - if ((ellt != RDES3_ELLT_IPHE) && (ellt != RDES3_ELLT_CSUM_ERR)) { - rx_pkt_cx->rxcsum |= OSI_CHECKSUM_UNNECESSARY; - } -} - -/** - * @brief mgbe_get_rx_hash - Get Rx packet hash from descriptor if valid - * - * Algorithm: This routine will be invoked by OSI layer itself to get received - * packet Hash from descriptor if RSS hash is valid and it also sets the type - * of RSS hash. - * - * @param[in] rx_desc: Rx Descriptor. - * @param[in] rx_pkt_cx: Per-Rx packet context structure - */ -static void mgbe_get_rx_hash(struct osi_rx_desc *rx_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - unsigned int pkt_type = rx_desc->rdes3 & RDES3_L34T; - - if ((rx_desc->rdes3 & RDES3_RSV) != RDES3_RSV) { - return; - } - - switch (pkt_type) { - case RDES3_L34T_IPV4_TCP: - case RDES3_L34T_IPV4_UDP: - case RDES3_L34T_IPV6_TCP: - case RDES3_L34T_IPV6_UDP: - rx_pkt_cx->rx_hash_type = OSI_RX_PKT_HASH_TYPE_L4; - break; - default: - rx_pkt_cx->rx_hash_type = OSI_RX_PKT_HASH_TYPE_L3; - break; - } - - /* Get Rx hash from RDES1 RSSH */ - rx_pkt_cx->rx_hash = rx_desc->rdes1; - rx_pkt_cx->flags |= OSI_PKT_CX_RSS; -} - -/** - * @brief mgbe_get_rx_hwstamp - Get Rx HW Time stamp - * - * Algorithm: - * 1) Check for TS availability. - * 2) call get_tx_tstamp_status if TS is valid or not. - * 3) If yes, set a bit and update nano seconds in rx_pkt_cx so that OSD - * layer can extract the time by checking this bit. - * - * @param[in] rx_desc: Rx descriptor - * @param[in] context_desc: Rx context descriptor - * @param[in] rx_pkt_cx: Rx packet context - * - * @retval -1 if TimeStamp is not available - * @retval 0 if TimeStamp is available. - */ -static int mgbe_get_rx_hwstamp(struct osi_dma_priv_data *osi_dma, - struct osi_rx_desc *rx_desc, - struct osi_rx_desc *context_desc, - struct osi_rx_pkt_cx *rx_pkt_cx) -{ - int retry; - - if ((rx_desc->rdes3 & RDES3_CDA) != RDES3_CDA) { - return -1; - } - - for (retry = 0; retry < 10; retry++) { - if (((context_desc->rdes3 & RDES3_OWN) == 0U) && - ((context_desc->rdes3 & RDES3_CTXT) == RDES3_CTXT) && - ((context_desc->rdes3 & RDES3_TSA) == RDES3_TSA) && - ((context_desc->rdes3 & RDES3_TSD) != RDES3_TSD)) { - if ((context_desc->rdes0 == OSI_INVALID_VALUE) && - (context_desc->rdes1 == OSI_INVALID_VALUE)) { - /* Invalid time stamp */ - return -1; - } - /* Update rx pkt context flags to indicate PTP */ - rx_pkt_cx->flags |= OSI_PKT_CX_PTP; - /* Time Stamp can be read */ - break; - } else { - /* TS not available yet, so retrying */ - osi_dma->osd_ops.udelay(OSI_DELAY_1US); - } - } - - if (retry == 10) { - /* Timed out waiting for Rx timestamp */ - return -1; - } - - rx_pkt_cx->ns = context_desc->rdes0 + - (OSI_NSEC_PER_SEC * context_desc->rdes1); - if (rx_pkt_cx->ns < context_desc->rdes0) { - /* Will not hit this case */ - return -1; - } - - return 0; -} - -void mgbe_init_desc_ops(struct desc_ops *d_ops) -{ - d_ops->get_rx_csum = mgbe_get_rx_csum; - d_ops->update_rx_err_stats = mgbe_update_rx_err_stats; - d_ops->get_rx_vlan = mgbe_get_rx_vlan; - d_ops->get_rx_hash = mgbe_get_rx_hash; - d_ops->get_rx_hwstamp = mgbe_get_rx_hwstamp; -} diff --git a/osi/dma/mgbe_desc.h b/osi/dma/mgbe_desc.h deleted file mode 100644 index 8b0d5d0..0000000 --- a/osi/dma/mgbe_desc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2020, 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 MGBE_DESC_H_ -#define MGBE_DESC_H_ - -/** - * @addtogroup MGBE MAC FRP Stats. - * - * @brief Values defined for the MGBE Flexible Receive Parser Receive Status - * @{ - */ -#define MGBE_RDES2_FRPSM OSI_BIT(10) -#define MGBE_RDES3_FRPSL OSI_BIT(14) -/** @} */ - -#endif /* MGBE_DESC_H_ */ - diff --git a/osi/dma/mgbe_dma.c b/osi/dma/mgbe_dma.c deleted file mode 100644 index eab9f3b..0000000 --- a/osi/dma/mgbe_dma.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 "../osi/common/common.h" -#include -#include "mgbe_dma.h" -#include "dma_local.h" - -/** - * @brief mgbe_disable_chan_tx_intr - Disables DMA Tx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - */ -static void mgbe_disable_chan_tx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); - cntrl &= ~MGBE_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief mgbe_enable_chan_tx_intr - Enable Tx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - */ -static void mgbe_enable_chan_tx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); - cntrl |= MGBE_VIRT_INTR_CHX_CNTRL_TX; - osi_writel(cntrl, (nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief mgbe_disable_chan_rx_intr - Disable Rx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * 3) Mapping of physical IRQ line to DMA channel need to be maintained at - * OSDependent layer and pass corresponding channel number. - */ -static void mgbe_disable_chan_rx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); - cntrl &= ~MGBE_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief mgbe_enable_chan_rx_intr - Enable Rx channel interrupts. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - */ -static void mgbe_enable_chan_rx_intr(void *addr, nveu32_t chan) -{ - nveu32_t cntrl; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - cntrl = osi_readl((nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); - cntrl |= MGBE_VIRT_INTR_CHX_CNTRL_RX; - osi_writel(cntrl, (nveu8_t *)addr + - MGBE_VIRT_INTR_CHX_CNTRL(chan)); -} - -/** - * @brief mgbe_set_tx_ring_len - Set DMA Tx ring length. - * - * Algorithm: Set DMA Tx channel ring length for specific channel. - * - * @param[in] osi_dma: OSI DMA data structure. - * @param[in] chan: DMA Tx channel number. - * @param[in] len: Length. - */ -static void mgbe_set_tx_ring_len(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len) -{ - void *addr = osi_dma->base; - nveu32_t value; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - value = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_TX_CNTRL2(chan)); - value |= (len & MGBE_DMA_RING_LENGTH_MASK); - osi_writel(value, (nveu8_t *)addr + MGBE_DMA_CHX_TX_CNTRL2(chan)); -} - -/** - * @brief mgbe_set_tx_ring_start_addr - Set DMA Tx ring base address. - * - * Algorithm: Sets DMA Tx ring base address for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * @param[in] tx_desc: Tx desc base addess. - */ -static void mgbe_set_tx_ring_start_addr(void *addr, nveu32_t chan, - nveu64_t tx_desc) -{ - nveu64_t temp; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - temp = H32(tx_desc); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_TDLH(chan)); - } - - temp = L32(tx_desc); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_TDLA(chan)); - } -} - -/** - * @brief mgbe_update_tx_tailptr - Updates DMA Tx ring tail pointer. - * - * Algorithm: Updates DMA Tx ring tail pointer for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Tx channel number. - * @param[in] tailptr: DMA Tx ring tail pointer. - * - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - */ -static void mgbe_update_tx_tailptr(void *addr, nveu32_t chan, - nveu64_t tailptr) -{ - nveu64_t temp; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - temp = L32(tailptr); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_TDTLP(chan)); - } -} - -/** - * @brief mgbe_set_rx_ring_len - Set Rx channel ring length. - * - * Algorithm: Sets DMA Rx channel ring length for specific DMA channel. - * - * @param[in] osi_dma: OSI DMA data structure. - * @param[in] chan: DMA Rx channel number. - * @param[in] len: Length - */ -static void mgbe_set_rx_ring_len(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t len) -{ - void *addr = osi_dma->base; - nveu32_t value; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - value = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_RX_CNTRL2(chan)); - value |= (len & MGBE_DMA_RING_LENGTH_MASK); - osi_writel(value, (nveu8_t *)addr + MGBE_DMA_CHX_RX_CNTRL2(chan)); -} - -/** - * @brief mgbe_set_rx_ring_start_addr - Set DMA Rx ring base address. - * - * Algorithm: Sets DMA Rx channel ring base address. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * @param[in] tx_desc: DMA Rx desc base address. - */ -static void mgbe_set_rx_ring_start_addr(void *addr, nveu32_t chan, - nveu64_t tx_desc) -{ - nveu64_t temp; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - temp = H32(tx_desc); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_RDLH(chan)); - } - - temp = L32(tx_desc); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_RDLA(chan)); - } -} - -/** - * @brief mgbe_update_rx_tailptr - Update Rx ring tail pointer - * - * Algorithm: Updates DMA Rx channel tail pointer for specific channel. - * - * @param[in] addr: Base address indicating the start of - * memory mapped IO region of the MAC. - * @param[in] chan: DMA Rx channel number. - * @param[in] tailptr: Tail pointer - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - */ -static void mgbe_update_rx_tailptr(void *addr, nveu32_t chan, - nveu64_t tailptr) -{ - nveu64_t temp; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - temp = H32(tailptr); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_RDTHP(chan)); - } - - temp = L32(tailptr); - if (temp < UINT_MAX) { - osi_writel((nveu32_t)temp, (nveu8_t *)addr + - MGBE_DMA_CHX_RDTLP(chan)); - } -} - -/** - * @brief mgbe_start_dma - Start DMA. - * - * Algorithm: Start Tx and Rx DMA for specific channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Tx/Rx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - */ -static void mgbe_start_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - nveu32_t val; - void *addr = osi_dma->base; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - /* start Tx DMA */ - val = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_TX_CTRL(chan)); - val |= OSI_BIT(0); - osi_writel(val, (nveu8_t *)addr + MGBE_DMA_CHX_TX_CTRL(chan)); - - /* start Rx DMA */ - val = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_RX_CTRL(chan)); - val |= OSI_BIT(0); - val &= ~OSI_BIT(31); - osi_writel(val, (nveu8_t *)addr + MGBE_DMA_CHX_RX_CTRL(chan)); -} - -/** - * @brief mgbe_stop_dma - Stop DMA. - * - * Algorithm: Start Tx and Rx DMA for specific channel. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA Tx/Rx channel number. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - */ -static void mgbe_stop_dma(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - nveu32_t val; - void *addr = osi_dma->base; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - /* stop Tx DMA */ - val = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_TX_CTRL(chan)); - val &= ~OSI_BIT(0); - osi_writel(val, (nveu8_t *)addr + MGBE_DMA_CHX_TX_CTRL(chan)); - - /* stop Rx DMA */ - val = osi_readl((nveu8_t *)addr + MGBE_DMA_CHX_RX_CTRL(chan)); - val &= ~OSI_BIT(0); - val |= OSI_BIT(31); - osi_writel(val, (nveu8_t *)addr + MGBE_DMA_CHX_RX_CTRL(chan)); -} - -/** - * @brief mgbe_configure_dma_channel - Configure DMA channel - * - * Algorithm: This takes care of configuring the below - * parameters for the DMA channel - * 1) Enabling DMA channel interrupts - * 2) Enable 8xPBL mode - * 3) Program Tx, Rx PBL - * 4) Enable TSO if HW supports - * 5) Program Rx Watchdog timer - * 6) Program Out Standing DMA Read Requests - * 7) Program Out Standing DMA write Requests - * - * @param[in] chan: DMA channel number that need to be configured. - * @param[in] owrq: out standing write dma requests - * @param[in] orrq: out standing read dma requests - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note MAC has to be out of reset. - */ -static void mgbe_configure_dma_channel(nveu32_t chan, - nveu32_t owrq, - nveu32_t orrq, - struct osi_dma_priv_data *osi_dma) -{ - nveu32_t value; - nveu32_t txpbl; - nveu32_t rxpbl; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - /* enable DMA channel interrupts */ - /* Enable TIE and TBUE */ - /* TIE - Transmit Interrupt Enable */ - /* TBUE - Transmit Buffer Unavailable Enable */ - /* RIE - Receive Interrupt Enable */ - /* RBUE - Receive Buffer Unavailable Enable */ - /* AIE - Abnormal Interrupt Summary Enable */ - /* NIE - Normal Interrupt Summary Enable */ - /* FBE - Fatal Bus Error Enable */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_INTR_ENA(chan)); - value |= MGBE_DMA_CHX_INTR_TIE | MGBE_DMA_CHX_INTR_TBUE | - MGBE_DMA_CHX_INTR_RIE | MGBE_DMA_CHX_INTR_RBUE | - MGBE_DMA_CHX_INTR_FBEE | MGBE_DMA_CHX_INTR_AIE | - MGBE_DMA_CHX_INTR_NIE; - - /* For multi-irqs to work nie needs to be disabled */ - /* TODO: do we need this ? */ - value &= ~(MGBE_DMA_CHX_INTR_NIE); - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_INTR_ENA(chan)); - - /* Enable 8xPBL mode */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_CTRL(chan)); - value |= MGBE_DMA_CHX_CTRL_PBLX8; - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_CTRL(chan)); - - /* Configure DMA channel Transmit control register */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_TX_CTRL(chan)); - /* Enable OSF mode */ - value |= MGBE_DMA_CHX_TX_CTRL_OSP; - - /* - * Formula for TxPBL calculation is - * (TxPBL) < ((TXQSize - MTU)/(DATAWIDTH/8)) - 5 - * if TxPBL exceeds the value of 256 then we need to make use of 256 - * as the TxPBL else we should be using the value whcih we get after - * calculation by using above formula - */ - if (osi_dma->pre_si == OSI_ENABLE) { - txpbl = ((((MGBE_TXQ_RXQ_SIZE_FPGA / osi_dma->num_dma_chans) - - osi_dma->mtu) / (MGBE_AXI_DATAWIDTH / 8U)) - 5U); - } else { - txpbl = ((((MGBE_TXQ_SIZE / osi_dma->num_dma_chans) - - osi_dma->mtu) / (MGBE_AXI_DATAWIDTH / 8U)) - 5U); - } - - /* Since PBLx8 is set, so txpbl/8 will be the value that - * need to be programmed - */ - if (txpbl >= MGBE_DMA_CHX_MAX_PBL) { - value |= ((MGBE_DMA_CHX_MAX_PBL / 8U) << - MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } else { - value |= ((txpbl / 8U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } - - /* enable TSO by default if HW supports */ - value |= MGBE_DMA_CHX_TX_CTRL_TSE; - - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_TX_CTRL(chan)); - - /* Configure DMA channel Receive control register */ - /* Select Rx Buffer size. Needs to be rounded up to next multiple of - * bus width - */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_CTRL(chan)); - - /* clear previous Rx buffer size */ - value &= ~MGBE_DMA_CHX_RBSZ_MASK; - value |= (osi_dma->rx_buf_len << MGBE_DMA_CHX_RBSZ_SHIFT); - /* RxPBL calculation is - * RxPBL <= Rx Queue Size/2 - */ - if (osi_dma->pre_si == OSI_ENABLE) { - rxpbl = (((MGBE_TXQ_RXQ_SIZE_FPGA / osi_dma->num_dma_chans) / - 2U) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } else { - rxpbl = (((MGBE_RXQ_SIZE / osi_dma->num_dma_chans) / 2U) << - MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } - /* Since PBLx8 is set, so rxpbl/8 will be the value that - * need to be programmed - */ - if (rxpbl >= MGBE_DMA_CHX_MAX_PBL) { - value |= ((MGBE_DMA_CHX_MAX_PBL / 8) << - MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } else { - value |= ((rxpbl / 8) << MGBE_DMA_CHX_CTRL_PBL_SHIFT); - } - - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_CTRL(chan)); - - /* Set Receive Interrupt Watchdog Timer Count */ - /* conversion of usec to RWIT value - * Eg:System clock is 62.5MHz, each clock cycle would then be 16ns - * For value 0x1 in watchdog timer,device would wait for 256 clk cycles, - * ie, (16ns x 256) => 4.096us (rounding off to 4us) - * So formula with above values is,ret = usec/4 - */ - /* NOTE: Bug 3287883: If RWTU value programmed then driver needs - * to follow below order - - * 1. First write RWT field with non-zero value. - * 2. Program RWTU field of register - * DMA_CH(#i)_Rx_Interrupt_Watchdog_Time. - */ - if ((osi_dma->use_riwt == OSI_ENABLE) && - (osi_dma->rx_riwt < UINT_MAX)) { - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_WDT(chan)); - /* Mask the RWT value */ - value &= ~MGBE_DMA_CHX_RX_WDT_RWT_MASK; - /* Conversion of usec to Rx Interrupt Watchdog Timer Count */ - /* TODO: Need to fix AXI clock for silicon */ - value |= ((osi_dma->rx_riwt * - ((nveu32_t)MGBE_AXI_CLK_FREQ / OSI_ONE_MEGA_HZ)) / - MGBE_DMA_CHX_RX_WDT_RWTU) & - MGBE_DMA_CHX_RX_WDT_RWT_MASK; - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_WDT(chan)); - - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_WDT(chan)); - value &= ~(MGBE_DMA_CHX_RX_WDT_RWTU_MASK << - MGBE_DMA_CHX_RX_WDT_RWTU_SHIFT); - value |= (MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE << - MGBE_DMA_CHX_RX_WDT_RWTU_SHIFT); - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_WDT(chan)); - } - - /* Update ORRQ in DMA_CH(#i)_Tx_Control2 register */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_TX_CNTRL2(chan)); - value |= (orrq << MGBE_DMA_CHX_TX_CNTRL2_ORRQ_SHIFT); - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_TX_CNTRL2(chan)); - - /* Update OWRQ in DMA_CH(#i)_Rx_Control2 register */ - value = osi_readl((nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_CNTRL2(chan)); - value |= (owrq << MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SHIFT); - osi_writel(value, (nveu8_t *)osi_dma->base + - MGBE_DMA_CHX_RX_CNTRL2(chan)); -} - -/** - * @brief mgbe_init_dma_channel - DMA channel INIT - * - * @param[in] osi_dma: OSI DMA private data structure. - */ -static nve32_t mgbe_init_dma_channel(struct osi_dma_priv_data *osi_dma) -{ - nveu32_t chinx; - nveu32_t owrq; - nveu32_t orrq; - - /* DMA Read Out Standing Requests */ - /* For Presi ORRQ is 16 in case of schannel and 64 in case of mchannel. - * For Si ORRQ is 64 in case of single and multi channel - */ - orrq = (MGBE_DMA_CHX_TX_CNTRL2_ORRQ_RECOMMENDED / - osi_dma->num_dma_chans); - if ((osi_dma->num_dma_chans == 1U) && (osi_dma->pre_si == OSI_ENABLE)) { - /* For Presi ORRQ is 16 in a single channel configuration - * so overwrite only for this configuration - */ - orrq = MGBE_DMA_CHX_RX_CNTRL2_ORRQ_SCHAN_PRESI; - } - - /* DMA Write Out Standing Requests */ - /* For Presi OWRQ is 8 and for Si it is 32 in case of single channel. - * For Multi Channel OWRQ is 64 for both si and presi - */ - if (osi_dma->num_dma_chans == 1U) { - if (osi_dma->pre_si == OSI_ENABLE) { - owrq = MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN_PRESI; - } else { - owrq = MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN; - } - } else { - owrq = (MGBE_DMA_CHX_RX_CNTRL2_OWRQ_MCHAN / - osi_dma->num_dma_chans); - } - - /* configure MGBE DMA channels */ - for (chinx = 0; chinx < osi_dma->num_dma_chans; chinx++) { - mgbe_configure_dma_channel(osi_dma->dma_chans[chinx], - owrq, orrq, osi_dma); - } - - return 0; -} - -/** - * @brief mgbe_set_rx_buf_len - Set Rx buffer length - * Sets the Rx buffer length based on the new MTU size set. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note 1) MAC needs to be out of reset and proper clocks need to be configured - * 2) DMA HW init need to be completed successfully, see osi_hw_dma_init - * 3) osi_dma->mtu need to be filled with current MTU size <= 9K - */ -static void mgbe_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) -{ - nveu32_t rx_buf_len; - - /* Add Ethernet header + FCS + NET IP align size to MTU */ - rx_buf_len = osi_dma->mtu + OSI_ETH_HLEN + - NV_VLAN_HLEN + OSI_NET_IP_ALIGN; - /* Buffer alignment */ - osi_dma->rx_buf_len = ((rx_buf_len + (MGBE_AXI_BUS_WIDTH - 1U)) & - ~(MGBE_AXI_BUS_WIDTH - 1U)); -} - -/** - * @brief Read-validate HW registers for functional safety. - * - * @note - * Algorithm: - * - Reads pre-configured list of MAC/MTL configuration registers - * and compares with last written value for any modifications. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @pre - * - MAC has to be out of reset. - * - osi_hw_dma_init has to be called. Internally this would initialize - * the safety_config (see osi_dma_priv_data) based on MAC version and - * which specific registers needs to be validated periodically. - * - Invoke this call if (osi_dma_priv_data->safety_config != OSI_NULL) - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t mgbe_validate_dma_regs(OSI_UNUSED - struct osi_dma_priv_data *osi_dma) -{ - /* TODO: for mgbe */ - return 0; -} - -/** - * @brief mgbe_clear_vm_tx_intr - Clear VM Tx interrupt - * - * Algorithm: Clear Tx interrupt source at DMA and wrapper level. - * - * @param[in] addr: MAC base address. - * @param[in] chan: DMA Tx channel number. - */ -static void mgbe_clear_vm_tx_intr(void *addr, nveu32_t chan) -{ -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - osi_writel(MGBE_DMA_CHX_STATUS_CLEAR_TX, - (nveu8_t *)addr + MGBE_DMA_CHX_STATUS(chan)); - osi_writel(MGBE_VIRT_INTR_CHX_STATUS_TX, - (nveu8_t *)addr + MGBE_VIRT_INTR_CHX_STATUS(chan)); - - mgbe_disable_chan_tx_intr(addr, chan); -} - -/** - * @brief mgbe_clear_vm_rx_intr - Clear VM Rx interrupt - * - * @param[in] addr: MAC base address. - * @param[in] chan: DMA Tx channel number. - * - * Algorithm: Clear Rx interrupt source at DMA and wrapper level. - */ -static void mgbe_clear_vm_rx_intr(void *addr, nveu32_t chan) -{ -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - osi_writel(MGBE_DMA_CHX_STATUS_CLEAR_RX, - (nveu8_t *)addr + MGBE_DMA_CHX_STATUS(chan)); - osi_writel(MGBE_VIRT_INTR_CHX_STATUS_RX, - (nveu8_t *)addr + MGBE_VIRT_INTR_CHX_STATUS(chan)); - - mgbe_disable_chan_rx_intr(addr, chan); -} - -/** - * @brief mgbe_config_slot - Configure slot Checking for DMA channel - * - * Algorithm: Set/Reset the slot function of DMA channel based on given inputs - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA channel number to enable slot function - * @param[in] set: flag for set/reset with value OSI_ENABLE/OSI_DISABLE - * @param[in] interval: slot interval fixed for MGBE - its 125usec - * - * @note 1) MAC should be init and started. see osi_start_mac() - * 2) OSD should be initialized - * - */ -static void mgbe_config_slot(struct osi_dma_priv_data *osi_dma, - unsigned int chan, - unsigned int set, - OSI_UNUSED unsigned int interval) -{ - unsigned int value; -#if 0 - MGBE_CHECK_CHAN_BOUND(chan); -#endif - if (set == OSI_ENABLE) { - /* Program SLOT CTRL register SIV and set ESC bit */ - value = osi_readl((unsigned char *)osi_dma->base + - MGBE_DMA_CHX_SLOT_CTRL(chan)); - /* Set ESC bit */ - value |= MGBE_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + - MGBE_DMA_CHX_SLOT_CTRL(chan)); - - } else { - /* Clear ESC bit of SLOT CTRL register */ - value = osi_readl((unsigned char *)osi_dma->base + - MGBE_DMA_CHX_SLOT_CTRL(chan)); - value &= ~MGBE_DMA_CHX_SLOT_ESC; - osi_writel(value, (unsigned char *)osi_dma->base + - MGBE_DMA_CHX_SLOT_CTRL(chan)); - } -} - -void mgbe_init_dma_chan_ops(struct dma_chan_ops *ops) -{ - ops->set_tx_ring_len = mgbe_set_tx_ring_len; - ops->set_rx_ring_len = mgbe_set_rx_ring_len; - ops->set_tx_ring_start_addr = mgbe_set_tx_ring_start_addr; - ops->set_rx_ring_start_addr = mgbe_set_rx_ring_start_addr; - ops->update_tx_tailptr = mgbe_update_tx_tailptr; - ops->update_rx_tailptr = mgbe_update_rx_tailptr; - ops->disable_chan_tx_intr = mgbe_disable_chan_tx_intr; - ops->enable_chan_tx_intr = mgbe_enable_chan_tx_intr; - ops->disable_chan_rx_intr = mgbe_disable_chan_rx_intr; - ops->enable_chan_rx_intr = mgbe_enable_chan_rx_intr; - ops->start_dma = mgbe_start_dma; - ops->stop_dma = mgbe_stop_dma; - ops->init_dma_channel = mgbe_init_dma_channel; - ops->set_rx_buf_len = mgbe_set_rx_buf_len; - ops->validate_regs = mgbe_validate_dma_regs; - ops->clear_vm_tx_intr = mgbe_clear_vm_tx_intr; - ops->clear_vm_rx_intr = mgbe_clear_vm_rx_intr; - ops->config_slot = mgbe_config_slot; -}; diff --git a/osi/dma/mgbe_dma.h b/osi/dma/mgbe_dma.h deleted file mode 100644 index 9321501..0000000 --- a/osi/dma/mgbe_dma.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2020-2022, 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 INCLUDED_MGBE_DMA_H -#define INCLUDED_MGBE_DMA_H - -/** - * @addtogroup MGBE AXI Clock defines - * - * @brief AXI Clock defines - * @{ - */ -#define MGBE_AXI_CLK_FREQ 480000000U -/** @} */ - -/** - * @@addtogroup Timestamp Capture Register - * @brief MGBE MAC Timestamp Register offset - * @{ - */ -#define MGBE_MAC_TSS 0X0D20 -#define MGBE_MAC_TS_NSEC 0x0D30 -#define MGBE_MAC_TS_SEC 0x0D34 -#define MGBE_MAC_TS_PID 0x0D38 -/** @} */ - -/** - * @addtogroup MGBE_DMA DMA Channel Register offsets - * - * @brief MGBE DMA Channel register offsets - * @{ - */ -#define MGBE_DMA_CHX_TX_CTRL(x) ((0x0080U * (x)) + 0x3104U) -#define MGBE_DMA_CHX_RX_CTRL(x) ((0x0080U * (x)) + 0x3108U) -#define MGBE_DMA_CHX_SLOT_CTRL(x) ((0x0080U * (x)) + 0x310CU) -#define MGBE_DMA_CHX_INTR_ENA(x) ((0x0080U * (x)) + 0x3138U) -#define MGBE_DMA_CHX_CTRL(x) ((0x0080U * (x)) + 0x3100U) -#define MGBE_DMA_CHX_RX_WDT(x) ((0x0080U * (x)) + 0x313CU) -#define MGBE_DMA_CHX_TX_CNTRL2(x) ((0x0080U * (x)) + 0x3130U) -#define MGBE_DMA_CHX_RX_CNTRL2(x) ((0x0080U * (x)) + 0x3134U) -#define MGBE_DMA_CHX_TDLH(x) ((0x0080U * (x)) + 0x3110U) -#define MGBE_DMA_CHX_TDLA(x) ((0x0080U * (x)) + 0x3114U) -#define MGBE_DMA_CHX_TDTLP(x) ((0x0080U * (x)) + 0x3124U) -#define MGBE_DMA_CHX_TDTHP(x) ((0x0080U * (x)) + 0x3120U) -#define MGBE_DMA_CHX_RDLH(x) ((0x0080U * (x)) + 0x3118U) -#define MGBE_DMA_CHX_RDLA(x) ((0x0080U * (x)) + 0x311CU) -#define MGBE_DMA_CHX_RDTHP(x) ((0x0080U * (x)) + 0x3128U) -#define MGBE_DMA_CHX_RDTLP(x) ((0x0080U * (x)) + 0x312CU) -/** @} */ - -/** - * @addtogroup MGBE_INTR INT Channel Register offsets - * - * @brief MGBE Virtural Interrupt Channel register offsets - * @{ - */ -#define MGBE_VIRT_INTR_CHX_STATUS(x) (0x8604U + ((x) * 8U)) -#define MGBE_VIRT_INTR_CHX_CNTRL(x) (0x8600U + ((x) * 8U)) -#define MGBE_VIRT_INTR_APB_CHX_CNTRL(x) (0x8200U + ((x) * 4U)) -/** @} */ - -/** - * @addtogroup MGBE_BIT BIT fields for MGBE channel registers - * - * @brief Values defined for the MGBE registers - * @{ - */ -#define MGBE_DMA_CHX_TX_CTRL_OSP OSI_BIT(4) -#define MGBE_DMA_CHX_TX_CTRL_TSE OSI_BIT(12) -#define MGBE_DMA_CHX_RX_WDT_RWT_MASK 0xFFU -#define MGBE_DMA_CHX_RX_WDT_RWTU 2048U -#define MGBE_DMA_CHX_RX_WDT_RWTU_2048_CYCLE 3U -#define MGBE_DMA_CHX_RX_WDT_RWTU_MASK 3U -#define MGBE_DMA_CHX_RX_WDT_RWTU_SHIFT 12U -#define MGBE_DMA_CHX_RBSZ_MASK 0x7FFEU -#define MGBE_DMA_CHX_RBSZ_SHIFT 1U -#define MGBE_AXI_BUS_WIDTH 0x10U -#define MGBE_DMA_CHX_CTRL_PBLX8 OSI_BIT(16) -#define MGBE_DMA_CHX_INTR_TIE OSI_BIT(0) -#define MGBE_DMA_CHX_INTR_TBUE OSI_BIT(2) -#define MGBE_DMA_CHX_INTR_RIE OSI_BIT(6) -#define MGBE_DMA_CHX_INTR_RBUE OSI_BIT(7) -#define MGBE_DMA_CHX_INTR_FBEE OSI_BIT(12) -#define MGBE_DMA_CHX_INTR_AIE OSI_BIT(14) -#define MGBE_DMA_CHX_INTR_NIE OSI_BIT(15) -#define MGBE_DMA_CHX_STATUS_TI OSI_BIT(0) -#define MGBE_DMA_CHX_STATUS_RI OSI_BIT(6) -#define MGBE_DMA_CHX_STATUS_NIS OSI_BIT(15) -#define MGBE_DMA_CHX_SLOT_ESC OSI_BIT(0) -#define MGBE_DMA_CHX_STATUS_CLEAR_TX (MGBE_DMA_CHX_STATUS_TI | \ - MGBE_DMA_CHX_STATUS_NIS) -#define MGBE_DMA_CHX_STATUS_CLEAR_RX (MGBE_DMA_CHX_STATUS_RI | \ - MGBE_DMA_CHX_STATUS_NIS) -#define MGBE_VIRT_INTR_CHX_STATUS_TX OSI_BIT(0) -#define MGBE_VIRT_INTR_CHX_STATUS_RX OSI_BIT(1) -#define MGBE_VIRT_INTR_CHX_CNTRL_TX OSI_BIT(0) -#define MGBE_VIRT_INTR_CHX_CNTRL_RX OSI_BIT(1) -#define MGBE_DMA_CHX_TX_CNTRL2_ORRQ_RECOMMENDED 64U -#define MGBE_DMA_CHX_TX_CNTRL2_ORRQ_SHIFT 24U -#define MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN 32U -#define MGBE_DMA_CHX_RX_CNTRL2_OWRQ_MCHAN 64U -#define MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SHIFT 24U -#define MGBE_DMA_CHX_RX_CNTRL2_OWRQ_SCHAN_PRESI 8U -#define MGBE_DMA_CHX_RX_CNTRL2_ORRQ_SCHAN_PRESI 16U -#define MGBE_DMA_RING_LENGTH_MASK 0xFFFFU -#define MGBE_DMA_CHX_CTRL_PBL_SHIFT 16U -/** @} */ - -/** - * @addtogroup MGBE PBL settings. - * - * @brief Values defined for PBL settings - * @{ - */ -/* Tx and Rx Qsize is 64KB */ -#define MGBE_TXQ_RXQ_SIZE_FPGA 65536U -/* Tx Queue size is 128KB */ -#define MGBE_TXQ_SIZE 131072U -/* Rx Queue size is 192KB */ -#define MGBE_RXQ_SIZE 196608U -/* MAX PBL value */ -#define MGBE_DMA_CHX_MAX_PBL 256U -/* AXI Data width */ -#define MGBE_AXI_DATAWIDTH 128U -/** @} */ - -/** - * @addtogroup MGBE MAC timestamp registers bit field. - * - * @brief Values defined for the MGBE timestamp registers - * @{ - */ -#define MGBE_MAC_TSS_TXTSC OSI_BIT(15) -#define MGBE_MAC_TS_PID_MASK 0x3FFU -#define MGBE_MAC_TS_NSEC_MASK 0x7FFFFFFFU -/** @} */ - -/** - * @brief mgbe_get_dma_chan_ops - MGBE get DMA channel operations - * - * Algorithm: Returns pointer DMA channel operations structure. - * - * @returns Pointer to DMA channel operations structure - */ -struct osi_dma_chan_ops *mgbe_get_dma_chan_ops(void); -#endif diff --git a/osi/dma/osi_dma.c b/osi/dma/osi_dma.c deleted file mode 100644 index 6d7e16f..0000000 --- a/osi/dma/osi_dma.c +++ /dev/null @@ -1,922 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 "dma_local.h" -#include -#include "hw_desc.h" -#include "../osi/common/common.h" -#ifdef OSI_DEBUG -#include "debug.h" -#endif /* OSI_DEBUG */ -#include "hw_common.h" - -/** - * @brief g_dma - DMA local data array. - */ -static struct dma_local g_dma[MAX_DMA_INSTANCES]; - -/** - * @brief g_ops - local DMA HW operations array. - */ -static struct dma_chan_ops g_ops[MAX_MAC_IP_TYPES]; - -struct osi_dma_priv_data *osi_get_dma(void) -{ - nveu32_t i; - - for (i = 0U; i < MAX_DMA_INSTANCES; i++) { - if (g_dma[i].init_done == OSI_ENABLE) { - continue; - } - - break; - } - - if (i == MAX_DMA_INSTANCES) { - return OSI_NULL; - } - - g_dma[i].magic_num = (nveu64_t)&g_dma[i].osi_dma; - - return &g_dma[i].osi_dma; -} - -/** - * @brief Function to validate input arguments of API. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] l_dma: Local OSI DMA data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t validate_args(struct osi_dma_priv_data *osi_dma, - struct dma_local *l_dma) -{ - if ((osi_dma == OSI_NULL) || (osi_dma->base == OSI_NULL) || - (l_dma->init_done == OSI_DISABLE)) { - return -1; - } - - return 0; -} - -/** - * @brief Function to validate input arguments of API. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: DMA channel number. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t validate_dma_chan_num(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (chan >= l_dma->max_chans) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid DMA channel number\n", chan); - return -1; - } - - return 0; -} - -/** - * @brief Function to validate array of DMA channels. - * - * @param[in] osi_dma: OSI DMA private data structure. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: Yes - * - De-initialization: Yes - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static inline nve32_t validate_dma_chans(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t i = 0; - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - if (osi_dma->dma_chans[i] > l_dma->max_chans) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid DMA channel number:\n", - osi_dma->dma_chans[i]); - return -1; - } - } - - return 0; -} - -/** - * @brief Function to validate function pointers. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] ops_p: Pointer to OSI DMA channel operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on Success - * @retval -1 on Failure - */ -static nve32_t validate_func_ptrs(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops_p) -{ - nveu32_t i = 0; - void *temp_ops = (void *)ops_p; -#if __SIZEOF_POINTER__ == 8 - nveu64_t *l_ops = (nveu64_t *)temp_ops; -#elif __SIZEOF_POINTER__ == 4 - nveu32_t *l_ops = (nveu32_t *)temp_ops; -#else - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Undefined architecture\n", 0ULL); - return -1; -#endif - - for (i = 0; i < (sizeof(*ops_p) / (nveu64_t)__SIZEOF_POINTER__); i++) { - if (*l_ops == 0U) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: fn ptr validation failed at\n", - (nveu64_t)i); - return -1; - } - - l_ops++; - } - - return 0; -} - -nve32_t osi_init_dma_ops(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t default_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_DEFAULT_RING_SZ }; - nveu32_t max_rz[] = { EQOS_DEFAULT_RING_SZ, MGBE_MAX_RING_SZ }; - typedef void (*init_ops_arr)(struct dma_chan_ops *temp); - typedef void *(*safety_init)(void); - - init_ops_arr i_ops[MAX_MAC_IP_TYPES] = { - eqos_init_dma_chan_ops, mgbe_init_dma_chan_ops - }; - - safety_init s_init[MAX_MAC_IP_TYPES] = { - eqos_get_dma_safety_config, OSI_NULL - }; - - if (osi_dma == OSI_NULL) { - return -1; - } - - if ((l_dma->magic_num != (nveu64_t)osi_dma) || - (l_dma->init_done == OSI_ENABLE)) { - return -1; - } - - if (osi_dma->is_ethernet_server != OSI_ENABLE) { - if ((osi_dma->osd_ops.transmit_complete == OSI_NULL) || - (osi_dma->osd_ops.receive_packet == OSI_NULL) || - (osi_dma->osd_ops.ops_log == OSI_NULL) || -#ifdef OSI_DEBUG - (osi_dma->osd_ops.printf == OSI_NULL) || -#endif /* OSI_DEBUG */ - (osi_dma->osd_ops.udelay == OSI_NULL)) { - return -1; - } - } - - if (osi_dma->mac > OSI_MAC_HW_MGBE) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Invalid MAC HW type\n", 0ULL); - return -1; - } - - if ((osi_dma->tx_ring_sz == 0U) || - !(is_power_of_two(osi_dma->tx_ring_sz)) || - (osi_dma->tx_ring_sz < HW_MIN_RING_SZ) || - (osi_dma->tx_ring_sz > default_rz[osi_dma->mac])) { - osi_dma->tx_ring_sz = default_rz[osi_dma->mac]; - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Using default Tx ring size: \n", - osi_dma->tx_ring_sz); - } - - if ((osi_dma->rx_ring_sz == 0U) || - !(is_power_of_two(osi_dma->rx_ring_sz)) || - (osi_dma->rx_ring_sz < HW_MIN_RING_SZ) || - (osi_dma->rx_ring_sz > max_rz[osi_dma->mac])) { - osi_dma->rx_ring_sz = default_rz[osi_dma->mac]; - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Using default rx ring size: \n", - osi_dma->tx_ring_sz); - } - - i_ops[osi_dma->mac](&g_ops[osi_dma->mac]); - - if (s_init[osi_dma->mac] != OSI_NULL) { - osi_dma->safety_config = s_init[osi_dma->mac](); - } - - if (init_desc_ops(osi_dma) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA desc ops init failed\n", 0ULL); - return -1; - } - - if (validate_func_ptrs(osi_dma, &g_ops[osi_dma->mac]) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA ops validation failed\n", 0ULL); - return -1; - } - - l_dma->ops_p = &g_ops[osi_dma->mac]; - l_dma->init_done = OSI_ENABLE; - - return 0; -} - -nve32_t osi_hw_dma_init(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t i, chan; - nve32_t ret; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - l_dma->mac_ver = osi_readl((nveu8_t *)osi_dma->base + MAC_VERSION) & - MAC_VERSION_SNVER_MASK; - if (validate_mac_ver_update_chans(l_dma->mac_ver, - &l_dma->max_chans) == 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid MAC version\n", (nveu64_t)l_dma->mac_ver); - return -1; - } - - if (osi_dma->num_dma_chans > l_dma->max_chans) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid number of DMA channels\n", 0ULL); - return -1; - } - - if (validate_dma_chans(osi_dma) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA channels validation failed\n", 0ULL); - return -1; - } - - ret = l_dma->ops_p->init_dma_channel(osi_dma); - if (ret < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: init dma channel failed\n", 0ULL); - return ret; - } - - ret = dma_desc_init(osi_dma, l_dma->ops_p); - if (ret != 0) { - return ret; - } - - if ((l_dma->mac_ver != OSI_EQOS_MAC_4_10) && - (l_dma->mac_ver != OSI_EQOS_MAC_5_00)) { - l_dma->vm_intr = OSI_ENABLE; - } - - /* Enable channel interrupts at wrapper level and start DMA */ - for (i = 0; i < osi_dma->num_dma_chans; i++) { - chan = osi_dma->dma_chans[i]; - - l_dma->ops_p->enable_chan_tx_intr(osi_dma->base, chan); - l_dma->ops_p->enable_chan_rx_intr(osi_dma->base, chan); - l_dma->ops_p->start_dma(osi_dma, chan); - } - - /** - * OSD will update this if PTP needs to be run in diffrent modes. - * Default configuration is PTP sync in two step sync with slave mode. - */ - if (osi_dma->ptp_flag == 0U) { - osi_dma->ptp_flag = (OSI_PTP_SYNC_SLAVE | OSI_PTP_SYNC_TWOSTEP); - } - - return 0; -} - -nve32_t osi_hw_dma_deinit(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t i; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (osi_dma->num_dma_chans > l_dma->max_chans) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "Invalid number of DMA channels\n", 0ULL); - return -1; - } - - if (validate_dma_chans(osi_dma) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA channels validation failed\n", 0ULL); - return -1; - } - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - l_dma->ops_p->stop_dma(osi_dma, osi_dma->dma_chans[i]); - } - - /* FIXME: Need to fix */ -// l_dma->magic_num = 0; -// l_dma->init_done = OSI_DISABLE; - - return 0; -} - -nve32_t osi_disable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->disable_chan_tx_intr(osi_dma->base, chan); - - return 0; -} - -nve32_t osi_enable_chan_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->enable_chan_tx_intr(osi_dma->base, chan); - - return 0; -} - -nve32_t osi_disable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->disable_chan_rx_intr(osi_dma->base, chan); - - return 0; -} - -nve32_t osi_enable_chan_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->enable_chan_rx_intr(osi_dma->base, chan); - - return 0; -} - -nve32_t osi_clear_vm_tx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->clear_vm_tx_intr(osi_dma->base, chan); - - return 0; -} - -nve32_t osi_clear_vm_rx_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->clear_vm_rx_intr(osi_dma->base, chan); - - return 0; -} - -nveu32_t osi_get_global_dma_status(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return 0; - } - - return osi_readl((nveu8_t *)osi_dma->base + HW_GLOBAL_DMA_STATUS); -} - -nve32_t osi_handle_dma_intr(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t tx_rx, - nveu32_t en_dis) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - typedef void (*dma_intr_fn)(void *base, nveu32_t ch); - dma_intr_fn fn[2][2][2] = { - { { l_dma->ops_p->disable_chan_tx_intr, l_dma->ops_p->enable_chan_tx_intr }, - { l_dma->ops_p->disable_chan_rx_intr, l_dma->ops_p->enable_chan_rx_intr } }, - { { l_dma->ops_p->clear_vm_tx_intr, l_dma->ops_p->enable_chan_tx_intr }, - { l_dma->ops_p->clear_vm_rx_intr, l_dma->ops_p->enable_chan_rx_intr } } - }; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - if ((tx_rx > OSI_DMA_CH_RX_INTR) || - (en_dis > OSI_DMA_INTR_ENABLE)) { - return -1; - } - - fn[l_dma->vm_intr][tx_rx][en_dis](osi_dma->base, chan); - - return 0; -} - -nve32_t osi_start_dma(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->start_dma(osi_dma, chan); - - return 0; -} - -nve32_t osi_stop_dma(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - return -1; - } - - l_dma->ops_p->stop_dma(osi_dma, chan); - - return 0; -} - -nveu32_t osi_get_refill_rx_desc_cnt(struct osi_dma_priv_data *osi_dma, - unsigned int chan) -{ - struct osi_rx_ring *rx_ring = osi_dma->rx_ring[chan]; - - if ((rx_ring == OSI_NULL) || - (rx_ring->cur_rx_idx >= osi_dma->rx_ring_sz) || - (rx_ring->refill_idx >= osi_dma->rx_ring_sz)) { - return 0; - } - - return (rx_ring->cur_rx_idx - rx_ring->refill_idx) & - (osi_dma->rx_ring_sz - 1U); -} - -/** - * @brief rx_dma_desc_validate_args - DMA Rx descriptor init args Validate - * - * Algorithm: Validates DMA Rx descriptor init argments. - * - * @param[in] osi_dma: OSI DMA private data struture. - * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. - * @param[in] chan: Rx DMA channel number - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t rx_dma_desc_validate_args( - struct osi_dma_priv_data *osi_dma, - struct dma_local *l_dma, - struct osi_rx_ring *rx_ring, - nveu32_t chan) -{ - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - if (!((rx_ring != OSI_NULL) && (rx_ring->rx_swcx != OSI_NULL) && - (rx_ring->rx_desc != OSI_NULL))) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid pointers\n", 0ULL); - return -1; - } - - if (validate_dma_chan_num(osi_dma, chan) < 0) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid channel\n", 0ULL); - return -1; - } - - return 0; -} - -/** - * @brief rx_dma_handle_ioc - DMA Rx descriptor RWIT Handler - * - * Algorithm: - * 1) Check RWIT enable and reset IOC bit - * 2) Check rx_frames enable and update IOC bit - * - * @param[in] osi_dma: OSI DMA private data struture. - * @param[in] rx_ring: HW ring corresponding to Rx DMA channel. - * @param[in, out] rx_desc: Rx Rx descriptor. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - */ -static inline void rx_dma_handle_ioc(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, - struct osi_rx_desc *rx_desc) -{ - /* reset IOC bit if RWIT is enabled */ - if (osi_dma->use_riwt == OSI_ENABLE) { - rx_desc->rdes3 &= ~RDES3_IOC; - /* update IOC bit if rx_frames is enabled. Rx_frames - * can be enabled only along with RWIT. - */ - if (osi_dma->use_rx_frames == OSI_ENABLE) { - if ((rx_ring->refill_idx % - osi_dma->rx_frames) == OSI_NONE) { - rx_desc->rdes3 |= RDES3_IOC; - } - } - } -} - -nve32_t osi_rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct osi_rx_ring *rx_ring, nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu64_t tailptr = 0; - struct osi_rx_swcx *rx_swcx = OSI_NULL; - struct osi_rx_desc *rx_desc = OSI_NULL; - - if (rx_dma_desc_validate_args(osi_dma, l_dma, rx_ring, chan) < 0) { - /* Return on arguments validation failure */ - return -1; - } - - /* Refill buffers */ - while ((rx_ring->refill_idx != rx_ring->cur_rx_idx) && - (rx_ring->refill_idx < osi_dma->rx_ring_sz)) { - rx_swcx = rx_ring->rx_swcx + rx_ring->refill_idx; - rx_desc = rx_ring->rx_desc + rx_ring->refill_idx; - - if ((rx_swcx->flags & OSI_RX_SWCX_BUF_VALID) != - OSI_RX_SWCX_BUF_VALID) { - break; - } - - rx_swcx->flags = 0; - - /* Populate the newly allocated buffer address */ - rx_desc->rdes0 = L32(rx_swcx->buf_phy_addr); - rx_desc->rdes1 = H32(rx_swcx->buf_phy_addr); - - rx_desc->rdes2 = 0; - rx_desc->rdes3 = RDES3_IOC; - - if (osi_dma->mac == OSI_MAC_HW_EQOS) { - rx_desc->rdes3 |= RDES3_B1V; - } - - /* Reset IOC bit if RWIT is enabled */ - rx_dma_handle_ioc(osi_dma, rx_ring, rx_desc); - rx_desc->rdes3 |= RDES3_OWN; - - INCR_RX_DESC_INDEX(rx_ring->refill_idx, osi_dma->rx_ring_sz); - } - - /* Update the Rx tail ptr whenever buffer is replenished to - * kick the Rx DMA to resume if it is in suspend. Always set - * Rx tailptr to 1 greater than last descriptor in the ring since HW - * knows to loop over to start of ring. - */ - tailptr = rx_ring->rx_desc_phy_addr + - (sizeof(struct osi_rx_desc) * (osi_dma->rx_ring_sz)); - - if (osi_unlikely(tailptr < rx_ring->rx_desc_phy_addr)) { - /* Will not hit this case, used for CERT-C compliance */ - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma: Invalid tailptr\n", 0ULL); - return -1; - } - - l_dma->ops_p->update_rx_tailptr(osi_dma->base, chan, tailptr); - - return 0; -} - -nve32_t osi_set_rx_buf_len(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - l_dma->ops_p->set_rx_buf_len(osi_dma); - - return 0; -} - -nve32_t osi_dma_get_systime_from_mac(struct osi_dma_priv_data *const osi_dma, - nveu32_t *sec, nveu32_t *nsec) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - common_get_systime_from_mac(osi_dma->base, osi_dma->mac, sec, nsec); - - return 0; -} - -nveu32_t osi_is_mac_enabled(struct osi_dma_priv_data *const osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return OSI_DISABLE; - } - - return common_is_mac_enabled(osi_dma->base, osi_dma->mac); -} - -nve32_t osi_hw_transmit(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (osi_unlikely(validate_args(osi_dma, l_dma) < 0)) { - return -1; - } - - if (osi_unlikely(validate_dma_chan_num(osi_dma, chan) < 0)) { - return -1; - } - - if (osi_unlikely(osi_dma->tx_ring[chan] == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Invalid Tx ring\n", 0ULL); - return -1; - } - - return hw_transmit(osi_dma, osi_dma->tx_ring[chan], l_dma->ops_p, chan); -} - -nve32_t osi_dma_ioctl(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - struct osi_dma_ioctl_data *data; - - if (osi_unlikely(validate_args(osi_dma, l_dma) < 0)) { - return -1; - } - - data = &osi_dma->ioctl_data; - - switch (data->cmd) { -#ifdef OSI_DEBUG - case OSI_DMA_IOCTL_CMD_REG_DUMP: - reg_dump(osi_dma); - break; - case OSI_DMA_IOCTL_CMD_STRUCTS_DUMP: - structs_dump(osi_dma); - break; -#endif /* OSI_DEBUG */ - default: - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "DMA: Invalid IOCTL command", 0ULL); - return -1; - } - - return 0; -} - -#ifndef OSI_STRIPPED_LIB - -/** - * @brief osi_slot_args_validate - Validate slot function arguments - * - * @note - * Algorithm: - * - Check set argument and return error. - * - Validate osi_dma structure pointers. - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] set: Flag to set with OSI_ENABLE and reset with OSI_DISABLE - * - * @pre MAC should be init and started. see osi_start_mac() - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t osi_slot_args_validate(struct osi_dma_priv_data *osi_dma, - struct dma_local *l_dma, - nveu32_t set) -{ - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - /* return on invalid set argument */ - if ((set != OSI_ENABLE) && (set != OSI_DISABLE)) { - OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, - "dma: Invalid set argument\n", set); - return -1; - } - - return 0; -} - -nve32_t osi_config_slot_function(struct osi_dma_priv_data *osi_dma, - nveu32_t set) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - nveu32_t i = 0U, chan = 0U, interval = 0U; - struct osi_tx_ring *tx_ring = OSI_NULL; - - /* Validate arguments */ - if (osi_slot_args_validate(osi_dma, l_dma, set) < 0) { - return -1; - } - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - /* Get DMA channel and validate */ - chan = osi_dma->dma_chans[i]; - - if ((chan == 0x0U) || - (chan >= l_dma->max_chans)) { - /* Ignore 0 and invalid channels */ - continue; - } - - /* Check for slot enable */ - if (osi_dma->slot_enabled[chan] == OSI_ENABLE) { - /* Get DMA slot interval and validate */ - interval = osi_dma->slot_interval[chan]; - if (interval > OSI_SLOT_INTVL_MAX) { - OSI_DMA_ERR(osi_dma->osd, - OSI_LOG_ARG_INVALID, - "dma: Invalid interval arguments\n", - interval); - return -1; - } - - tx_ring = osi_dma->tx_ring[chan]; - if (tx_ring == OSI_NULL) { - OSI_DMA_ERR(osi_dma->osd, OSI_LOG_ARG_INVALID, - "tx_ring is null\n", chan); - return -1; - } - tx_ring->slot_check = set; - l_dma->ops_p->config_slot(osi_dma, chan, set, interval); - } - } - - return 0; -} - -nve32_t osi_validate_dma_regs(struct osi_dma_priv_data *osi_dma) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (validate_args(osi_dma, l_dma) < 0) { - return -1; - } - - return l_dma->ops_p->validate_regs(osi_dma); -} - -nve32_t osi_txring_empty(struct osi_dma_priv_data *osi_dma, nveu32_t chan) -{ - struct osi_tx_ring *tx_ring = osi_dma->tx_ring[chan]; - - return (tx_ring->clean_idx == tx_ring->cur_tx_idx) ? 1 : 0; -} -#endif /* !OSI_STRIPPED_LIB */ diff --git a/osi/dma/osi_dma_txrx.c b/osi/dma/osi_dma_txrx.c deleted file mode 100644 index 336ed32..0000000 --- a/osi/dma/osi_dma_txrx.c +++ /dev/null @@ -1,1395 +0,0 @@ -/* - * Copyright (c) 2018-2022, 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 "dma_local.h" -#include -#include "hw_desc.h" -#include "../osi/common/common.h" -#include "mgbe_dma.h" -#include "local_common.h" -#ifdef OSI_DEBUG -#include "debug.h" -#endif /* OSI_DEBUG */ - -static struct desc_ops d_ops[MAX_MAC_IP_TYPES]; - -/** - * @brief get_rx_err_stats - Detect Errors from Rx Descriptor - * - * @note - * Algorithm: - * - This routine will be invoked by OSI layer itself which - * checks for the Last Descriptor and updates the receive status errors - * accordingly. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in] rx_desc: Rx Descriptor. - * @param[in, out] pkt_err_stats: Packet error stats which stores the errors - * reported - */ -static inline void get_rx_err_stats(struct osi_rx_desc *rx_desc, - struct osi_pkt_err_stats *pkt_err_stats) -{ - /* increment rx crc if we see CE bit set */ - if ((rx_desc->rdes3 & RDES3_ERR_CRC) == RDES3_ERR_CRC) { - pkt_err_stats->rx_crc_error = - osi_update_stats_counter( - pkt_err_stats->rx_crc_error, - 1UL); - } - - /* increment rx frame error if we see RE bit set */ - if ((rx_desc->rdes3 & RDES3_ERR_RE) == RDES3_ERR_RE) { - pkt_err_stats->rx_frame_error = - osi_update_stats_counter( - pkt_err_stats->rx_frame_error, - 1UL); - } -} - -/** - * @brief validate_rx_completions_arg- Validate input argument of rx_completions - * - * @note - * Algorithm: - * - This routine validate input arguments to osi_process_rx_completions() - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: Rx DMA channel number - * @param[in] more_data_avail: Pointer to more data available flag. OSI fills - * this flag if more rx packets available to read(1) or not(0). - * @param[out] rx_ring: OSI DMA channel Rx ring - * @param[out] rx_pkt_cx: OSI DMA receive packet context - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t validate_rx_completions_arg( - struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - nveu32_t *more_data_avail, - struct osi_rx_ring **rx_ring, - struct osi_rx_pkt_cx **rx_pkt_cx) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (osi_unlikely((osi_dma == OSI_NULL) || - (more_data_avail == OSI_NULL) || - (chan >= l_dma->max_chans))) { - return -1; - } - - *rx_ring = osi_dma->rx_ring[chan]; - if (osi_unlikely(*rx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_input_rx_completions: Invalid pointers\n", - 0ULL); - return -1; - } - *rx_pkt_cx = &(*rx_ring)->rx_pkt_cx; - if (osi_unlikely(*rx_pkt_cx == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_input_rx_completions: Invalid pointers\n", - 0ULL); - return -1; - } - - return 0; -} - -nve32_t osi_process_rx_completions(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, nve32_t budget, - nveu32_t *more_data_avail) -{ - struct osi_rx_ring *rx_ring = OSI_NULL; - struct osi_rx_pkt_cx *rx_pkt_cx = OSI_NULL; - struct osi_rx_desc *rx_desc = OSI_NULL; - struct osi_rx_swcx *rx_swcx = OSI_NULL; - struct osi_rx_swcx *ptp_rx_swcx = OSI_NULL; - struct osi_rx_desc *context_desc = OSI_NULL; - nveu32_t ip_type = osi_dma->mac; - nve32_t received = 0; - nve32_t received_resv = 0; - nve32_t ret = 0; - - ret = validate_rx_completions_arg(osi_dma, chan, more_data_avail, - &rx_ring, &rx_pkt_cx); - if (osi_unlikely(ret < 0)) { - return ret; - } - - if (rx_ring->cur_rx_idx >= osi_dma->rx_ring_sz) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid cur_rx_idx\n", 0ULL); - return -1; - } - - /* Reset flag to indicate if more Rx frames available to OSD layer */ - *more_data_avail = OSI_NONE; - - while ((received < budget) && (received_resv < budget)) { - 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; - - /* check for data availability */ - if ((rx_desc->rdes3 & RDES3_OWN) == RDES3_OWN) { - break; - } -#ifdef OSI_DEBUG - if (osi_dma->enable_desc_dump == 1U) { - desc_dump(osi_dma, rx_ring->cur_rx_idx, - rx_ring->cur_rx_idx, RX_DESC_DUMP, chan); - } -#endif /* OSI_DEBUG */ - - INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, osi_dma->rx_ring_sz); - - if (osi_unlikely(rx_swcx->buf_virt_addr == - osi_dma->resv_buf_virt_addr)) { - rx_swcx->buf_virt_addr = OSI_NULL; - rx_swcx->buf_phy_addr = 0; - /* Reservered buffer used */ - received_resv++; - if (osi_dma->osd_ops.realloc_buf != OSI_NULL) { - osi_dma->osd_ops.realloc_buf(osi_dma->osd, - rx_ring, chan); - } - continue; - } - - /* packet already processed */ - if ((rx_swcx->flags & OSI_RX_SWCX_PROCESSED) == - OSI_RX_SWCX_PROCESSED) { - break; - } - - /* When JE is set, HW will accept any valid packet on Rx upto - * 9K or 16K (depending on GPSCLE bit), irrespective of whether - * MTU set is lower than these specific values. When Rx buf len - * is allocated to be exactly same as MTU, HW will consume more - * than 1 Rx desc. to place the larger packet and will set the - * LD bit in RDES3 accordingly. - * Restrict such Rx packets (which are longer than currently - * set MTU on DUT), and drop them in driver since HW cannot - * drop them. Also make use of swcx flags so that OSD can skip - * DMA buffer allocation and DMA mapping for those descriptors. - * If data is spread across multiple descriptors, drop packet - */ - if ((((rx_desc->rdes3 & RDES3_FD) == RDES3_FD) && - ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD)) == - BOOLEAN_FALSE) { - rx_swcx->flags |= OSI_RX_SWCX_REUSE; - continue; - } - - /* get the length of the packet */ - rx_pkt_cx->pkt_len = rx_desc->rdes3 & RDES3_PKT_LEN; - - /* Mark pkt as valid by default */ - rx_pkt_cx->flags |= OSI_PKT_CX_VALID; - - if ((rx_desc->rdes3 & RDES3_LD) == RDES3_LD) { - if ((rx_desc->rdes3 & - (((osi_dma->mac == OSI_MAC_HW_MGBE) ? - RDES3_ES_MGBE : RDES3_ES_BITS))) != 0U) { - /* reset validity if any of the error bits - * are set - */ - rx_pkt_cx->flags &= ~OSI_PKT_CX_VALID; - d_ops[ip_type].update_rx_err_stats(rx_desc, - &osi_dma->pkt_err_stats); - } - - /* Check if COE Rx checksum is valid */ - d_ops[ip_type].get_rx_csum(rx_desc, rx_pkt_cx); - - /* Get Rx VLAN from descriptor */ - d_ops[ip_type].get_rx_vlan(rx_desc, rx_pkt_cx); - - /* get_rx_hash for RSS */ - d_ops[ip_type].get_rx_hash(rx_desc, rx_pkt_cx); - - context_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; - /* Get rx time stamp */ - ret = d_ops[ip_type].get_rx_hwstamp(osi_dma, rx_desc, - context_desc, rx_pkt_cx); - if (ret == 0) { - ptp_rx_swcx = rx_ring->rx_swcx + - rx_ring->cur_rx_idx; - /* Marking software context as PTP software - * context so that OSD can skip DMA buffer - * allocation and DMA mapping. DMA can use PTP - * software context addresses directly since - * those are valid. - */ - ptp_rx_swcx->flags |= OSI_RX_SWCX_REUSE; -#ifdef OSI_DEBUG - if (osi_dma->enable_desc_dump == 1U) { - desc_dump(osi_dma, rx_ring->cur_rx_idx, - rx_ring->cur_rx_idx, RX_DESC_DUMP, - chan); - } -#endif /* OSI_DEBUG */ - /* Context descriptor was consumed. Its skb - * and DMA mapping will be recycled - */ - INCR_RX_DESC_INDEX(rx_ring->cur_rx_idx, osi_dma->rx_ring_sz); - } - if (osi_likely(osi_dma->osd_ops.receive_packet != - OSI_NULL)) { - osi_dma->osd_ops.receive_packet(osi_dma->osd, - rx_ring, chan, - osi_dma->rx_buf_len, - rx_pkt_cx, rx_swcx); - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid function pointer\n", - 0ULL); - return -1; - } - } - osi_dma->dstats.q_rx_pkt_n[chan] = - osi_update_stats_counter( - osi_dma->dstats.q_rx_pkt_n[chan], - 1UL); - osi_dma->dstats.rx_pkt_n = - osi_update_stats_counter(osi_dma->dstats.rx_pkt_n, 1UL); - received++; - } - - /* If budget is done, check if HW ring still has unprocessed - * Rx packets, so that the OSD layer can decide to schedule - * this function again. - */ - if ((received + received_resv) >= budget) { - rx_desc = rx_ring->rx_desc + rx_ring->cur_rx_idx; - rx_swcx = rx_ring->rx_swcx + rx_ring->cur_rx_idx; - if (((rx_swcx->flags & OSI_RX_SWCX_PROCESSED) != - OSI_RX_SWCX_PROCESSED) && - ((rx_desc->rdes3 & RDES3_OWN) != RDES3_OWN)) { - /* Next descriptor has owned by SW - * So set more data avail flag here. - */ - *more_data_avail = OSI_ENABLE; - } - } - - return received; -} - -/** - * @brief inc_tx_pkt_stats - Increment Tx packet count Stats - * - * @note - * Algorithm: - * - This routine will be invoked by OSI layer internally to increment - * stats for successfully transmitted packets on certain DMA channel. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in, out] osi_dma: Pointer to OSI DMA private data structure. - * @param[in] chan: DMA channel number for which stats should be incremented. - */ -static inline void inc_tx_pkt_stats(struct osi_dma_priv_data *osi_dma, - nveu32_t chan) -{ - osi_dma->dstats.q_tx_pkt_n[chan] = - osi_update_stats_counter(osi_dma->dstats.q_tx_pkt_n[chan], 1UL); - osi_dma->dstats.tx_pkt_n = - osi_update_stats_counter(osi_dma->dstats.tx_pkt_n, 1UL); -} - -/** - * @brief get_tx_err_stats - Detect Errors from Tx Status - * - * @note - * Algorithm: - * - This routine will be invoked by OSI layer itself which - * checks for the Last Descriptor and updates the transmit status errors - * accordingly. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in] tx_desc: Tx Descriptor. - * @param[in, out] pkt_err_stats: Packet error stats which stores the errors - * reported - */ -static inline void get_tx_err_stats(struct osi_tx_desc *tx_desc, - struct osi_pkt_err_stats *pkt_err_stats) -{ - /* IP Header Error */ - if ((tx_desc->tdes3 & TDES3_IP_HEADER_ERR) == TDES3_IP_HEADER_ERR) { - pkt_err_stats->ip_header_error = - osi_update_stats_counter( - pkt_err_stats->ip_header_error, - 1UL); - } - - /* Jabber timeout Error */ - if ((tx_desc->tdes3 & TDES3_JABBER_TIMEO_ERR) == - TDES3_JABBER_TIMEO_ERR) { - pkt_err_stats->jabber_timeout_error = - osi_update_stats_counter( - pkt_err_stats->jabber_timeout_error, - 1UL); - } - - /* Packet Flush Error */ - if ((tx_desc->tdes3 & TDES3_PKT_FLUSH_ERR) == TDES3_PKT_FLUSH_ERR) { - pkt_err_stats->pkt_flush_error = - osi_update_stats_counter( - pkt_err_stats->pkt_flush_error, 1UL); - } - - /* Payload Checksum Error */ - if ((tx_desc->tdes3 & TDES3_PL_CHK_SUM_ERR) == TDES3_PL_CHK_SUM_ERR) { - pkt_err_stats->payload_cs_error = - osi_update_stats_counter( - pkt_err_stats->payload_cs_error, 1UL); - } - - /* Loss of Carrier Error */ - if ((tx_desc->tdes3 & TDES3_LOSS_CARRIER_ERR) == - TDES3_LOSS_CARRIER_ERR) { - pkt_err_stats->loss_of_carrier_error = - osi_update_stats_counter( - pkt_err_stats->loss_of_carrier_error, - 1UL); - } - - /* No Carrier Error */ - if ((tx_desc->tdes3 & TDES3_NO_CARRIER_ERR) == TDES3_NO_CARRIER_ERR) { - pkt_err_stats->no_carrier_error = - osi_update_stats_counter( - pkt_err_stats->no_carrier_error, 1UL); - } - - /* Late Collision Error */ - if ((tx_desc->tdes3 & TDES3_LATE_COL_ERR) == TDES3_LATE_COL_ERR) { - pkt_err_stats->late_collision_error = - osi_update_stats_counter( - pkt_err_stats->late_collision_error, - 1UL); - } - - /* Excessive Collision Error */ - if ((tx_desc->tdes3 & TDES3_EXCESSIVE_COL_ERR) == - TDES3_EXCESSIVE_COL_ERR) { - pkt_err_stats->excessive_collision_error = - osi_update_stats_counter( - pkt_err_stats->excessive_collision_error, - 1UL); - } - - /* Excessive Deferal Error */ - if ((tx_desc->tdes3 & TDES3_EXCESSIVE_DEF_ERR) == - TDES3_EXCESSIVE_DEF_ERR) { - pkt_err_stats->excessive_deferal_error = - osi_update_stats_counter( - pkt_err_stats->excessive_deferal_error, - 1UL); - } - - /* Under Flow Error */ - if ((tx_desc->tdes3 & TDES3_UNDER_FLOW_ERR) == TDES3_UNDER_FLOW_ERR) { - pkt_err_stats->underflow_error = - osi_update_stats_counter(pkt_err_stats->underflow_error, - 1UL); - } -} - -#ifndef OSI_STRIPPED_LIB -nve32_t osi_clear_tx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) -{ - nve32_t ret = -1; - struct osi_pkt_err_stats *pkt_err_stats; - - if (osi_dma != OSI_NULL) { - pkt_err_stats = &osi_dma->pkt_err_stats; - /* Reset tx packet errors */ - pkt_err_stats->ip_header_error = 0U; - pkt_err_stats->jabber_timeout_error = 0U; - pkt_err_stats->pkt_flush_error = 0U; - pkt_err_stats->payload_cs_error = 0U; - pkt_err_stats->loss_of_carrier_error = 0U; - pkt_err_stats->no_carrier_error = 0U; - pkt_err_stats->late_collision_error = 0U; - pkt_err_stats->excessive_collision_error = 0U; - pkt_err_stats->excessive_deferal_error = 0U; - pkt_err_stats->underflow_error = 0U; - pkt_err_stats->clear_tx_err = - osi_update_stats_counter(pkt_err_stats->clear_tx_err, - 1UL); - ret = 0; - } - - return ret; -} - -nve32_t osi_clear_rx_pkt_err_stats(struct osi_dma_priv_data *osi_dma) -{ - nve32_t ret = -1; - struct osi_pkt_err_stats *pkt_err_stats; - - if (osi_dma != OSI_NULL) { - pkt_err_stats = &osi_dma->pkt_err_stats; - /* Reset Rx packet errors */ - pkt_err_stats->rx_crc_error = 0U; - pkt_err_stats->clear_tx_err = - osi_update_stats_counter(pkt_err_stats->clear_rx_err, - 1UL); - ret = 0; - } - - return ret; -} -#endif /* !OSI_STRIPPED_LIB */ - -/** - * @brief validate_tx_completions_arg- Validate input argument of tx_completions - * - * @note - * Algorithm: - * - This routine validate input arguments to osi_process_tx_completions() - * - * @param[in] osi_dma: OSI DMA private data structure. - * @param[in] chan: Tx DMA channel number - * @param[out] tx_ring: OSI DMA channel Rx ring - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t validate_tx_completions_arg( - struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - struct osi_tx_ring **tx_ring) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - - if (osi_unlikely((osi_dma == OSI_NULL) || - (chan >= l_dma->max_chans))) { - return -1; - } - - *tx_ring = osi_dma->tx_ring[chan]; - - if (osi_unlikely(*tx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "validate_tx_completions_arg: Invalid pointers\n", - 0ULL); - return -1; - } - - return 0; -} - -/** - * @brief is_ptp_twostep_or_slave_mode - check for dut in ptp 2step or slave - * mode - * - * @param[in] ptp_flag: osi statructure variable to identify current ptp - * configuration - * - * @retval 1 if condition is true - * @retval 0 if condition is false. - */ -static inline unsigned int is_ptp_twostep_or_slave_mode(unsigned int ptp_flag) -{ - return (((ptp_flag & OSI_PTP_SYNC_SLAVE) == OSI_PTP_SYNC_SLAVE) || - ((ptp_flag & OSI_PTP_SYNC_TWOSTEP) == OSI_PTP_SYNC_TWOSTEP)) ? - OSI_ENABLE : OSI_DISABLE; -} - -int osi_process_tx_completions(struct osi_dma_priv_data *osi_dma, - unsigned int chan, int budget) -{ - struct osi_tx_ring *tx_ring = OSI_NULL; - struct osi_txdone_pkt_cx *txdone_pkt_cx = OSI_NULL; - struct osi_tx_swcx *tx_swcx = OSI_NULL; - struct osi_tx_desc *tx_desc = OSI_NULL; - nveu32_t entry = 0U; - nveu64_t vartdes1; - nveul64_t ns; - nve32_t processed = 0; - nve32_t ret; - - ret = validate_tx_completions_arg(osi_dma, chan, &tx_ring); - if (osi_unlikely(ret < 0)) { - return ret; - } - - txdone_pkt_cx = &tx_ring->txdone_pkt_cx; - entry = tx_ring->clean_idx; - - osi_dma->dstats.tx_clean_n[chan] = - osi_update_stats_counter(osi_dma->dstats.tx_clean_n[chan], 1U); - - while ((entry != tx_ring->cur_tx_idx) && (entry < osi_dma->tx_ring_sz) && - (processed < budget)) { - osi_memset(txdone_pkt_cx, 0U, sizeof(*txdone_pkt_cx)); - - tx_desc = tx_ring->tx_desc + entry; - tx_swcx = tx_ring->tx_swcx + entry; - - if ((tx_desc->tdes3 & TDES3_OWN) == TDES3_OWN) { - break; - } - -#ifdef OSI_DEBUG - if (osi_dma->enable_desc_dump == 1U) { - desc_dump(osi_dma, entry, entry, - (TX_DESC_DUMP | TX_DESC_DUMP_TX_DONE), chan); - } -#endif /* OSI_DEBUG */ - - /* check for Last Descriptor */ - if ((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) { - if (((tx_desc->tdes3 & TDES3_ES_BITS) != 0U) && - (osi_dma->mac != OSI_MAC_HW_MGBE)) { - txdone_pkt_cx->flags |= OSI_TXDONE_CX_ERROR; - /* fill packet error stats */ - get_tx_err_stats(tx_desc, - &osi_dma->pkt_err_stats); - } else { - inc_tx_pkt_stats(osi_dma, chan); - } - - if (processed < INT_MAX) { - processed++; - } - } - - if (osi_dma->mac != OSI_MAC_HW_MGBE) { - /* check tx tstamp status */ - if (((tx_desc->tdes3 & TDES3_LD) == TDES3_LD) && - ((tx_desc->tdes3 & TDES3_CTXT) != TDES3_CTXT) && - ((tx_desc->tdes3 & TDES3_TTSS) == TDES3_TTSS)) { - /* tx timestamp captured for this packet */ - ns = tx_desc->tdes0; - vartdes1 = tx_desc->tdes1; - if (OSI_NSEC_PER_SEC > - (OSI_ULLONG_MAX / vartdes1)) { - /* Will not hit this case */ - } else if ((OSI_ULLONG_MAX - - (vartdes1 * OSI_NSEC_PER_SEC)) < ns) { - /* Will not hit this case */ - } else { - txdone_pkt_cx->flags |= - OSI_TXDONE_CX_TS; - txdone_pkt_cx->ns = ns + - (vartdes1 * OSI_NSEC_PER_SEC); - } - } else { - /* Do nothing here */ - } - } else if (((tx_swcx->flags & OSI_PKT_CX_PTP) == - OSI_PKT_CX_PTP) && - // if not master in onestep mode - /* TODO: Is this check needed and can be removed ? */ - (is_ptp_twostep_or_slave_mode(osi_dma->ptp_flag) == - OSI_ENABLE) && - ((tx_desc->tdes3 & TDES3_CTXT) == 0U)) { - txdone_pkt_cx->pktid = tx_swcx->pktid; - txdone_pkt_cx->flags |= OSI_TXDONE_CX_TS_DELAYED; - } else { - /* Do nothing here */ - } - - if ((tx_swcx->flags & OSI_PKT_CX_PAGED_BUF) == - OSI_PKT_CX_PAGED_BUF) { - txdone_pkt_cx->flags |= OSI_TXDONE_CX_PAGED_BUF; - } - - if (osi_likely(osi_dma->osd_ops.transmit_complete != - OSI_NULL)) { - /* if tx_swcx->len == -1 means this is context - * descriptor for PTP and TSO. Here length will be reset - * so that for PTP/TSO context descriptors length will - * not be added to tx_bytes - */ - if (tx_swcx->len == OSI_INVALID_VALUE) { - tx_swcx->len = 0; - } - osi_dma->osd_ops.transmit_complete(osi_dma->osd, - tx_swcx, - txdone_pkt_cx); - } else { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid function pointer\n", - 0ULL); - return -1; - } - - tx_desc->tdes3 = 0; - tx_desc->tdes2 = 0; - tx_desc->tdes1 = 0; - tx_desc->tdes0 = 0; - tx_swcx->len = 0; - - tx_swcx->buf_virt_addr = OSI_NULL; - tx_swcx->buf_phy_addr = 0; - tx_swcx->flags = 0; - INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); - - /* Don't wait to update tx_ring->clean-idx. It will - * be used by OSD layer to determine the num. of available - * descriptors in the ring, which will in turn be used to - * wake the corresponding transmit queue in OS layer. - */ - tx_ring->clean_idx = entry; - } - - return processed; -} - -/** - * @brief need_cntx_desc - Helper function to check if context desc is needed. - * - * @note - * Algorithm: - * - Check if transmit packet context flags are set - * - If set, set the context descriptor bit along - * with other context information in the transmit descriptor. - * - * @param[in, out] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in, out] tx_swcx: Pointer to transmit sw packet context structure - * @param[in, out] tx_desc: Pointer to transmit descriptor to be filled. - * @param[in] sync_mode: PTP sync mode to indetify. - * @param[in] mac: HW MAC ver - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @retval 0 - cntx desc not used - * @retval 1 - cntx desc used. - */ - -static inline nve32_t need_cntx_desc(struct osi_tx_pkt_cx *tx_pkt_cx, - struct osi_tx_swcx *tx_swcx, - struct osi_tx_desc *tx_desc, - unsigned int ptp_sync_flag, - unsigned int mac) -{ - nve32_t ret = 0; - - if (((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) || - ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) || - ((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP)) { - - if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { - /* Set context type */ - tx_desc->tdes3 |= TDES3_CTXT; - /* Fill VLAN Tag ID */ - tx_desc->tdes3 |= tx_pkt_cx->vtag_id; - /* Set VLAN TAG Valid */ - tx_desc->tdes3 |= TDES3_VLTV; - - if (tx_swcx->len == OSI_INVALID_VALUE) { - tx_swcx->len = NV_VLAN_HLEN; - } - ret = 1; - } - - if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { - /* Set context type */ - tx_desc->tdes3 |= TDES3_CTXT; - /* Fill MSS */ - tx_desc->tdes2 |= tx_pkt_cx->mss; - /* Set MSS valid */ - tx_desc->tdes3 |= TDES3_TCMSSV; - ret = 1; - } - - /* This part of code must be at the end of function */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) { - if ((mac == OSI_MAC_HW_EQOS) && - ((ptp_sync_flag & OSI_PTP_SYNC_TWOSTEP) == - OSI_PTP_SYNC_TWOSTEP)){ - /* return the current ret value */ - return ret; - } - - /* Set context type */ - tx_desc->tdes3 |= TDES3_CTXT; - /* in case of One-step sync */ - if ((ptp_sync_flag & OSI_PTP_SYNC_ONESTEP) == - OSI_PTP_SYNC_ONESTEP) { - /* Set TDES3_OSTC */ - tx_desc->tdes3 |= TDES3_OSTC; - tx_desc->tdes3 &= ~TDES3_TCMSSV; - } - - ret = 1; - } - } - - return ret; -} - -/** - * @brief is_ptp_onestep_and_master_mode - check for dut is in master and - * onestep mode - * - * @param[in] ptp_flag: osi statructure variable to identify current ptp - * configuration - * - * @retval 1 if condition is true - * @retval 0 if condition is false. - */ -static inline unsigned int is_ptp_onestep_and_master_mode(unsigned int ptp_flag) -{ - return (((ptp_flag & OSI_PTP_SYNC_MASTER) == OSI_PTP_SYNC_MASTER) && - ((ptp_flag & OSI_PTP_SYNC_ONESTEP) == OSI_PTP_SYNC_ONESTEP)) ? - OSI_ENABLE : OSI_DISABLE; -} - -/** - * @brief fill_first_desc - Helper function to fill the first transmit - * descriptor. - * - * @note - * Algorithm: - * - Update the buffer address and length of buffer in first desc. - * - Check if any features like HW checksum offload, TSO, VLAN insertion - * etc. are flagged in transmit packet context. If so, set the fields in - * first desc corresponding to those features. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in, out] tx_ring: DMA channel TX ring. - * @param[in, out] tx_pkt_cx: Pointer to transmit packet context structure - * @param[in, out] tx_desc: Pointer to transmit descriptor to be filled. - * @param[in] tx_swcx: Pointer to corresponding tx descriptor software context. - */ -static inline void fill_first_desc(struct osi_tx_ring *tx_ring, - struct osi_tx_pkt_cx *tx_pkt_cx, - struct osi_tx_desc *tx_desc, - struct osi_tx_swcx *tx_swcx, - unsigned int ptp_flag) -{ - tx_desc->tdes0 = L32(tx_swcx->buf_phy_addr); - tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr); - tx_desc->tdes2 = tx_swcx->len; - /* Mark it as First descriptor */ - tx_desc->tdes3 |= TDES3_FD; - - /* If HW checksum offload enabled, mark CIC bits of FD */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_CSUM) == OSI_PKT_CX_CSUM) { - tx_desc->tdes3 |= TDES3_HW_CIC_ALL; - } else { - if ((tx_pkt_cx->flags & OSI_PKT_CX_IP_CSUM) == - OSI_PKT_CX_IP_CSUM) { - /* If IP only Checksum enabled, mark fist bit of CIC */ - tx_desc->tdes3 |= TDES3_HW_CIC_IP_ONLY; - } - } - - /* Enable VTIR in normal descriptor for VLAN packet */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { - tx_desc->tdes2 |= TDES2_VTIR; - } - - /* if TS is set enable timestamping */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) { - tx_desc->tdes2 |= TDES2_TTSE; - tx_swcx->flags |= OSI_PKT_CX_PTP; - //ptp master mode in one step sync - if (is_ptp_onestep_and_master_mode(ptp_flag) == - OSI_ENABLE) { - tx_desc->tdes2 &= ~TDES2_TTSE; - } - } - - /* if LEN bit is set, update packet payload len */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_LEN) == OSI_PKT_CX_LEN) { - /* Update packet len in desc */ - tx_desc->tdes3 |= tx_pkt_cx->payload_len; - } - - /* Enable TSE bit and update TCP hdr, payload len */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { - tx_desc->tdes3 |= TDES3_TSE; - - /* Minimum value for THL field is 5 for TSO - * So divide L4 hdr len by 4 - * Typical TCP hdr len = 20B / 4 = 5 - */ - tx_pkt_cx->tcp_udp_hdrlen /= OSI_TSO_HDR_LEN_DIVISOR; - - /* Update hdr len in desc */ - tx_desc->tdes3 |= (tx_pkt_cx->tcp_udp_hdrlen << - TDES3_THL_SHIFT); - - /* Update TCP payload len in desc */ - tx_desc->tdes3 &= ~TDES3_TPL_MASK; - tx_desc->tdes3 |= tx_pkt_cx->payload_len; - } else { - if ((tx_ring->slot_check == OSI_ENABLE) && - (tx_ring->slot_number < OSI_SLOT_NUM_MAX)) { - /* Fill Slot number */ - tx_desc->tdes3 |= (tx_ring->slot_number << - TDES3_THL_SHIFT); - tx_ring->slot_number = ((tx_ring->slot_number + 1U) % - OSI_SLOT_NUM_MAX); - } - } -} - -/** - * @brief dmb_oshst() - Data memory barrier operation that waits only - * for stores to complete, and only to the outer shareable domain. - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - */ -static inline void dmb_oshst(void) -{ - __sync_synchronize(); -} - -/** - * @brief validate_ctx - validate inputs form tx_pkt_cx - * - * @note - * Algorithm: - * - Validate tx_pkt_cx with expected value - * - * @note - * API Group: - * - Initialization: No - * - Run time: Yes - * - De-initialization: No - * - * @param[in] osi_dma: OSI private data structure. - * @param[in] tx_pkt_cx: Pointer to transmit packet context structure - * - * @retval 0 on success - * @retval -1 on failure. - */ -static inline nve32_t validate_ctx(struct osi_dma_priv_data *osi_dma, - struct osi_tx_pkt_cx *tx_pkt_cx) -{ - if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { - if (osi_unlikely((tx_pkt_cx->tcp_udp_hdrlen / - OSI_TSO_HDR_LEN_DIVISOR) > TDES3_THL_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid TSO header len\n", - (nveul64_t)tx_pkt_cx->tcp_udp_hdrlen); - goto fail; - } else if (osi_unlikely(tx_pkt_cx->payload_len > - TDES3_TPL_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid TSO payload len\n", - (nveul64_t)tx_pkt_cx->payload_len); - goto fail; - } else if (osi_unlikely(tx_pkt_cx->mss > TDES2_MSS_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid MSS\n", - (nveul64_t)tx_pkt_cx->mss); - goto fail; - } - } else if ((tx_pkt_cx->flags & OSI_PKT_CX_LEN) == OSI_PKT_CX_LEN) { - if (osi_unlikely(tx_pkt_cx->payload_len > TDES3_PL_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid frame len\n", - (nveul64_t)tx_pkt_cx->payload_len); - goto fail; - } - } - - if (osi_unlikely(tx_pkt_cx->vtag_id > TDES3_VT_MASK)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid VTAG_ID\n", - (nveul64_t)tx_pkt_cx->vtag_id); - goto fail; - } - - return 0; -fail: - return -1; -} - -nve32_t hw_transmit(struct osi_dma_priv_data *osi_dma, - struct osi_tx_ring *tx_ring, - struct dma_chan_ops *ops, - nveu32_t chan) -{ - struct dma_local *l_dma = (struct dma_local *)osi_dma; - struct osi_tx_pkt_cx *tx_pkt_cx = OSI_NULL; - struct osi_tx_desc *first_desc = OSI_NULL; - struct osi_tx_desc *last_desc = OSI_NULL; - struct osi_tx_desc *tx_desc = OSI_NULL; - struct osi_tx_swcx *tx_swcx = OSI_NULL; - struct osi_tx_desc *cx_desc = OSI_NULL; -#ifdef OSI_DEBUG - nveu32_t f_idx = tx_ring->cur_tx_idx; - nveu32_t l_idx = 0; -#endif /* OSI_DEBUG */ - nve32_t cntx_desc_consumed; - nveu32_t pkt_id = 0x0U; - nveu32_t desc_cnt = 0U; - nveu64_t tailptr; - nveu32_t entry = 0U; - nveu32_t i; - - entry = tx_ring->cur_tx_idx; - if (entry >= osi_dma->tx_ring_sz) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid cur_tx_idx\n", 0ULL); - return -1; - } - - tx_desc = tx_ring->tx_desc + entry; - tx_swcx = tx_ring->tx_swcx + entry; - tx_pkt_cx = &tx_ring->tx_pkt_cx; - - desc_cnt = tx_pkt_cx->desc_cnt; - if (osi_unlikely(desc_cnt == 0U)) { - /* Will not hit this case */ - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid desc_cnt\n", 0ULL); - return -1; - } - - if (validate_ctx(osi_dma, tx_pkt_cx) < 0) { - return -1; - } - - /* Context descriptor for VLAN/TSO */ - if ((tx_pkt_cx->flags & OSI_PKT_CX_VLAN) == OSI_PKT_CX_VLAN) { - osi_dma->dstats.tx_vlan_pkt_n = - osi_update_stats_counter(osi_dma->dstats.tx_vlan_pkt_n, - 1UL); - } - - if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) { - osi_dma->dstats.tx_tso_pkt_n = - osi_update_stats_counter(osi_dma->dstats.tx_tso_pkt_n, - 1UL); - } - - cntx_desc_consumed = need_cntx_desc(tx_pkt_cx, tx_swcx, tx_desc, - osi_dma->ptp_flag, osi_dma->mac); - if (cntx_desc_consumed == 1) { - if (((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) && - (osi_dma->mac == OSI_MAC_HW_MGBE)) { - /* mark packet id valid */ - tx_desc->tdes3 |= TDES3_PIDV; - if ((osi_dma->ptp_flag & OSI_PTP_SYNC_ONESTEP) == - OSI_PTP_SYNC_ONESTEP) { - /* packet ID for Onestep is 0x0 always */ - pkt_id = OSI_NONE; - } else { - pkt_id = GET_TX_TS_PKTID(l_dma->pkt_id, chan); - } - /* update packet id */ - tx_desc->tdes0 = pkt_id; - } - INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); - - /* Storing context descriptor to set DMA_OWN at last */ - cx_desc = tx_desc; - tx_desc = tx_ring->tx_desc + entry; - tx_swcx = tx_ring->tx_swcx + entry; - - desc_cnt--; - } - - /* Fill first descriptor */ - fill_first_desc(tx_ring, tx_pkt_cx, tx_desc, tx_swcx, osi_dma->ptp_flag); - if (((tx_pkt_cx->flags & OSI_PKT_CX_PTP) == OSI_PKT_CX_PTP) && - (osi_dma->mac == OSI_MAC_HW_MGBE)) { - /* save packet id for first desc, time stamp will be with - * first FD only - */ - tx_swcx->pktid = pkt_id; - } - - INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); - - first_desc = tx_desc; - last_desc = tx_desc; - tx_desc = tx_ring->tx_desc + entry; - tx_swcx = tx_ring->tx_swcx + entry; - desc_cnt--; - - /* Fill remaining descriptors */ - for (i = 0; i < desc_cnt; i++) { - tx_desc->tdes0 = L32(tx_swcx->buf_phy_addr); - tx_desc->tdes1 = H32(tx_swcx->buf_phy_addr); - tx_desc->tdes2 = tx_swcx->len; - /* set HW OWN bit for descriptor*/ - tx_desc->tdes3 |= TDES3_OWN; - - INCR_TX_DESC_INDEX(entry, osi_dma->tx_ring_sz); - last_desc = tx_desc; - tx_desc = tx_ring->tx_desc + entry; - tx_swcx = tx_ring->tx_swcx + entry; - } - - /* Mark it as LAST descriptor */ - last_desc->tdes3 |= TDES3_LD; - /* set Interrupt on Completion*/ - last_desc->tdes2 |= TDES2_IOC; - - if (tx_ring->frame_cnt < UINT_MAX) { - tx_ring->frame_cnt++; - } else if ((osi_dma->use_tx_frames == OSI_ENABLE) && - ((tx_ring->frame_cnt % osi_dma->tx_frames) < UINT_MAX)) { - /* make sure count for tx_frame interrupt logic is retained */ - tx_ring->frame_cnt = (tx_ring->frame_cnt % osi_dma->tx_frames) - + 1U; - } else { - tx_ring->frame_cnt = 1U; - } - - /* clear IOC bit if tx SW timer based coalescing is enabled */ - if (osi_dma->use_tx_usecs == OSI_ENABLE) { - last_desc->tdes2 &= ~TDES2_IOC; - - /* update IOC bit if tx_frames is enabled. Tx_frames - * can be enabled only along with tx_usecs. - */ - if (osi_dma->use_tx_frames == OSI_ENABLE) { - if ((tx_ring->frame_cnt % osi_dma->tx_frames) == - OSI_NONE) { - last_desc->tdes2 |= TDES2_IOC; - } - } - } - /* Set OWN bit for first and context descriptors - * at the end to avoid race condition - */ - first_desc->tdes3 |= TDES3_OWN; - if (cntx_desc_consumed == 1) { - cx_desc->tdes3 |= TDES3_OWN; - } - - /* - * We need to make sure Tx descriptor updated above is really updated - * before setting up the DMA, hence add memory write barrier here. - */ - dmb_oshst(); - -#ifdef OSI_DEBUG - if (osi_dma->enable_desc_dump == 1U) { - l_idx = entry; - desc_dump(osi_dma, f_idx, DECR_TX_DESC_INDEX(l_idx, osi_dma->tx_ring_sz), - (TX_DESC_DUMP | TX_DESC_DUMP_TX), chan); - } -#endif /* OSI_DEBUG */ - - tailptr = tx_ring->tx_desc_phy_addr + - (entry * sizeof(struct osi_tx_desc)); - if (osi_unlikely(tailptr < tx_ring->tx_desc_phy_addr)) { - /* Will not hit this case */ - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid tx_desc_phy_addr\n", 0ULL); - return -1; - } - - /* - * Updating cur_tx_idx allows tx completion thread to read first_desc. - * Hence cur_tx_idx should be updated after memory barrier. - */ - tx_ring->cur_tx_idx = entry; - - ops->update_tx_tailptr(osi_dma->base, chan, tailptr); - - return 0; -} - -/** - * @brief rx_dma_desc_initialization - Initialize DMA Receive descriptors for Rx - * - * @note - * Algorithm: - * - Initialize Receive descriptors with DMA mappable buffers, - * set OWN bit, Rx ring length and set starting address of Rx DMA channel. - * Tx ring base address in Tx DMA registers. - * - * @param[in, out] osi_dma: OSI private data structure. - * @param[in] chan: Rx channel number. - * @param[in] ops: DMA channel operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t rx_dma_desc_initialization(struct osi_dma_priv_data *osi_dma, - nveu32_t chan, - struct dma_chan_ops *ops) -{ - struct osi_rx_ring *rx_ring = OSI_NULL; - struct osi_rx_desc *rx_desc = OSI_NULL; - struct osi_rx_swcx *rx_swcx = OSI_NULL; - nveu64_t tailptr = 0; - nveu32_t i; - nve32_t ret = 0; - - rx_ring = osi_dma->rx_ring[chan]; - if (osi_unlikely(rx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid argument\n", 0ULL); - return -1; - }; - - rx_ring->cur_rx_idx = 0; - rx_ring->refill_idx = 0; - - for (i = 0; i < osi_dma->rx_ring_sz; i++) { - rx_swcx = rx_ring->rx_swcx + i; - rx_desc = rx_ring->rx_desc + i; - - /* Zero initialize the descriptors first */ - rx_desc->rdes0 = 0; - rx_desc->rdes1 = 0; - rx_desc->rdes2 = 0; - rx_desc->rdes3 = 0; - - rx_desc->rdes0 = L32(rx_swcx->buf_phy_addr); - rx_desc->rdes1 = H32(rx_swcx->buf_phy_addr); - rx_desc->rdes2 = 0; - rx_desc->rdes3 = RDES3_IOC; - - if (osi_dma->mac == OSI_MAC_HW_EQOS) { - rx_desc->rdes3 |= RDES3_B1V; - } - - /* reconfigure INTE bit if RX watchdog timer is enabled */ - if (osi_dma->use_riwt == OSI_ENABLE) { - rx_desc->rdes3 &= ~RDES3_IOC; - if (osi_dma->use_rx_frames == OSI_ENABLE) { - if ((i % osi_dma->rx_frames) == OSI_NONE) { - /* update IOC bit if rx_frames is - * enabled. Rx_frames can be enabled - * only along with RWIT. - */ - rx_desc->rdes3 |= RDES3_IOC; - } - } - } - rx_desc->rdes3 |= RDES3_OWN; - - rx_swcx->flags = 0; - } - - tailptr = rx_ring->rx_desc_phy_addr + - (sizeof(struct osi_rx_desc) * (osi_dma->rx_ring_sz)); - - if (osi_unlikely((tailptr < rx_ring->rx_desc_phy_addr))) { - /* Will not hit this case */ - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid phys address\n", 0ULL); - return -1; - } - - ops->set_rx_ring_len(osi_dma, chan, (osi_dma->rx_ring_sz - 1U)); - ops->update_rx_tailptr(osi_dma->base, chan, tailptr); - ops->set_rx_ring_start_addr(osi_dma->base, chan, - rx_ring->rx_desc_phy_addr); - - return ret; -} - -/** - * @brief rx_dma_desc_init - Initialize DMA Receive descriptors for Rx channel. - * - * @note - * Algorithm: - * - Initialize Receive descriptors with DMA mappable buffers, - * set OWN bit, Rx ring length and set starting address of Rx DMA channel. - * Tx ring base address in Tx DMA registers. - * - * @param[in, out] osi_dma: OSI private data structure. - * @param[in] ops: DMA channel operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t rx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops) -{ - nveu32_t chan = 0; - nveu32_t i; - nve32_t ret = 0; - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - chan = osi_dma->dma_chans[i]; - - ret = rx_dma_desc_initialization(osi_dma, chan, ops); - if (ret != 0) { - return ret; - } - } - - return ret; -} - -/** - * @brief tx_dma_desc_init - Initialize DMA Transmit descriptors. - * - * @note - * Algorithm: - * - Initialize Transmit descriptors and set Tx ring length, - * Tx ring base address in Tx DMA registers. - * - * @param[in, out] osi_dma: OSI DMA private data structure. - * @param[in] ops: DMA channel operations. - * - * @note - * API Group: - * - Initialization: Yes - * - Run time: No - * - De-initialization: No - * - * @retval 0 on success - * @retval -1 on failure. - */ -static nve32_t tx_dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops) -{ - struct osi_tx_ring *tx_ring = OSI_NULL; - struct osi_tx_desc *tx_desc = OSI_NULL; - struct osi_tx_swcx *tx_swcx = OSI_NULL; - nveu32_t chan = 0; - nveu32_t i, j; - - for (i = 0; i < osi_dma->num_dma_chans; i++) { - chan = osi_dma->dma_chans[i]; - - tx_ring = osi_dma->tx_ring[chan]; - if (osi_unlikely(tx_ring == OSI_NULL)) { - OSI_DMA_ERR(OSI_NULL, OSI_LOG_ARG_INVALID, - "dma_txrx: Invalid pointers\n", 0ULL); - return -1; - } - - for (j = 0; j < osi_dma->tx_ring_sz; j++) { - tx_desc = tx_ring->tx_desc + j; - tx_swcx = tx_ring->tx_swcx + j; - - tx_desc->tdes0 = 0; - tx_desc->tdes1 = 0; - tx_desc->tdes2 = 0; - tx_desc->tdes3 = 0; - - tx_swcx->len = 0; - tx_swcx->buf_virt_addr = OSI_NULL; - tx_swcx->buf_phy_addr = 0; - tx_swcx->flags = 0; - } - - tx_ring->cur_tx_idx = 0; - tx_ring->clean_idx = 0; - - /* Slot function parameter initialization */ - tx_ring->slot_number = 0U; - tx_ring->slot_check = OSI_DISABLE; - - ops->set_tx_ring_len(osi_dma, chan, - (osi_dma->tx_ring_sz - 1U)); - ops->set_tx_ring_start_addr(osi_dma->base, chan, - tx_ring->tx_desc_phy_addr); - } - - return 0; -} - -nve32_t dma_desc_init(struct osi_dma_priv_data *osi_dma, - struct dma_chan_ops *ops) -{ - nve32_t ret = 0; - - ret = tx_dma_desc_init(osi_dma, ops); - if (ret != 0) { - return ret; - } - - ret = rx_dma_desc_init(osi_dma, ops); - if (ret != 0) { - return ret; - } - - return ret; -} - -nve32_t init_desc_ops(struct osi_dma_priv_data *osi_dma) -{ - typedef void (*desc_ops_arr)(struct desc_ops *); - - desc_ops_arr desc_ops[2] = { - eqos_init_desc_ops, mgbe_init_desc_ops - }; - - desc_ops[osi_dma->mac](&d_ops[osi_dma->mac]); - - /* TODO: validate function pointers */ - return 0; -} diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl deleted file mode 100755 index d898e1a..0000000 --- a/scripts/checkpatch.pl +++ /dev/null @@ -1,7101 +0,0 @@ -#!/usr/bin/env perl -# SPDX-License-Identifier: GPL-2.0 -# -# (c) 2001, Dave Jones. (the file handling bit) -# (c) 2005, Joel Schopp (the ugly bit) -# (c) 2007,2008, Andy Whitcroft (new conditions, test suite) -# (c) 2008-2010 Andy Whitcroft -# (c) 2010-2018 Joe Perches - -use strict; -use warnings; -use POSIX; -use File::Basename; -use Cwd 'abs_path'; -use Term::ANSIColor qw(:constants); -use Encode qw(decode encode); - -my $P = $0; -my $D = dirname(abs_path($P)); - -my $V = '0.32'; - -use Getopt::Long qw(:config no_auto_abbrev); - -my $quiet = 0; -my $tree = 1; -my $chk_signoff = 1; -my $ignore_changeid = 1; -my $chk_patch = 1; -my $tst_only; -my $emacs = 0; -my $terse = 0; -my $showfile = 0; -my $file = 0; -my $git = 0; -my %git_commits = (); -my $check = 0; -my $check_orig = 0; -my $summary = 1; -my $mailback = 0; -my $summary_file = 0; -my $show_types = 0; -my $list_types = 0; -my $fix = 0; -my $fix_inplace = 0; -my $root; -my $gitroot = $ENV{'GIT_DIR'}; -$gitroot = ".git" if !defined($gitroot); -my %debug; -my %camelcase = (); -my %use_type = (); -my @use = (); -my %ignore_type = (); -my @ignore = (); -my $help = 0; -my $configuration_file = ".checkpatch.conf"; -my $max_line_length = 100; -my $ignore_perl_version = 0; -my $minimum_perl_version = 5.10.0; -my $min_conf_desc_length = 4; -my $spelling_file = "$D/spelling.txt"; -my $codespell = 0; -my $codespellfile = "/usr/share/codespell/dictionary.txt"; -my $conststructsfile = "$D/const_structs.checkpatch"; -my $typedefsfile; -my $color = "auto"; -my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE -# git output parsing needs US English output, so first set backtick child process LANGUAGE -my $git_command ='export LANGUAGE=en_US.UTF-8; git'; -my $tabsize = 8; -my ${CONFIG_} = "CONFIG_"; - -sub help { - my ($exitcode) = @_; - - print << "EOM"; -Usage: $P [OPTION]... [FILE]... -Version: $V - -Options: - -q, --quiet quiet - --no-tree run without a kernel tree - --no-signoff do not check for 'Signed-off-by' line - --ignore-changeid ignore Gerrit Change-Id - --patch treat FILE as patchfile (default) - --emacs emacs compile window format - --terse one line per report - --showfile emit diffed file position, not input file position - -g, --git treat FILE as a single commit or git revision range - single git commit with: - - ^ - ~n - multiple git commits with: - .. - ... - - - git merges are ignored - -f, --file treat FILE as regular source file - --subjective, --strict enable more subjective tests - --list-types list the possible message types - --types TYPE(,TYPE2...) show only these comma separated message types - --ignore TYPE(,TYPE2...) ignore various comma separated message types - --show-types show the specific message type in the output - --max-line-length=n set the maximum line length, (default $max_line_length) - if exceeded, warn on patches - requires --strict for use with --file - --min-conf-desc-length=n set the min description length, if shorter, warn - --tab-size=n set the number of spaces for tab (default $tabsize) - --root=PATH PATH to the kernel tree root - --no-summary suppress the per-file summary - --mailback only produce a report in case of warnings/errors - --summary-file include the filename in summary - --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of - 'values', 'possible', 'type', and 'attr' (default - is all off) - --test-only=WORD report only warnings/errors containing WORD - literally - --fix EXPERIMENTAL - may create horrible results - If correctable single-line errors exist, create - ".EXPERIMENTAL-checkpatch-fixes" - with potential errors corrected to the preferred - checkpatch style - --fix-inplace EXPERIMENTAL - may create horrible results - Is the same as --fix, but overwrites the input - file. It's your fault if there's no backup or git - --ignore-perl-version override checking of perl version. expect - runtime errors. - --codespell Use the codespell dictionary for spelling/typos - (default:/usr/share/codespell/dictionary.txt) - --codespellfile Use this codespell dictionary - --typedefsfile Read additional types from this file - --color[=WHEN] Use colors 'always', 'never', or only when output - is a terminal ('auto'). Default is 'auto'. - --kconfig-prefix=WORD use WORD as a prefix for Kconfig symbols (default - ${CONFIG_}) - -h, --help, --version display this help and exit - -When FILE is - read standard input. -EOM - - exit($exitcode); -} - -sub uniq { - my %seen; - return grep { !$seen{$_}++ } @_; -} - -sub list_types { - my ($exitcode) = @_; - - my $count = 0; - - local $/ = undef; - - open(my $script, '<', abs_path($P)) or - die "$P: Can't read '$P' $!\n"; - - my $text = <$script>; - close($script); - - my @types = (); - # Also catch when type or level is passed through a variable - for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) { - push (@types, $_); - } - @types = sort(uniq(@types)); - print("#\tMessage type\n\n"); - foreach my $type (@types) { - print(++$count . "\t" . $type . "\n"); - } - - exit($exitcode); -} - -my $conf = which_conf($configuration_file); -if (-f $conf) { - my @conf_args; - open(my $conffile, '<', "$conf") - or warn "$P: Can't find a readable $configuration_file file $!\n"; - - while (<$conffile>) { - my $line = $_; - - $line =~ s/\s*\n?$//g; - $line =~ s/^\s*//g; - $line =~ s/\s+/ /g; - - next if ($line =~ m/^\s*#/); - next if ($line =~ m/^\s*$/); - - my @words = split(" ", $line); - foreach my $word (@words) { - last if ($word =~ m/^#/); - push (@conf_args, $word); - } - } - close($conffile); - unshift(@ARGV, @conf_args) if @conf_args; -} - -# Perl's Getopt::Long allows options to take optional arguments after a space. -# Prevent --color by itself from consuming other arguments -foreach (@ARGV) { - if ($_ eq "--color" || $_ eq "-color") { - $_ = "--color=$color"; - } -} - -GetOptions( - 'q|quiet+' => \$quiet, - 'tree!' => \$tree, - 'signoff!' => \$chk_signoff, - 'ignore-changeid!' => \$ignore_changeid, - 'patch!' => \$chk_patch, - 'emacs!' => \$emacs, - 'terse!' => \$terse, - 'showfile!' => \$showfile, - 'f|file!' => \$file, - 'g|git!' => \$git, - 'subjective!' => \$check, - 'strict!' => \$check, - 'ignore=s' => \@ignore, - 'types=s' => \@use, - 'show-types!' => \$show_types, - 'list-types!' => \$list_types, - 'max-line-length=i' => \$max_line_length, - 'min-conf-desc-length=i' => \$min_conf_desc_length, - 'tab-size=i' => \$tabsize, - 'root=s' => \$root, - 'summary!' => \$summary, - 'mailback!' => \$mailback, - 'summary-file!' => \$summary_file, - 'fix!' => \$fix, - 'fix-inplace!' => \$fix_inplace, - 'ignore-perl-version!' => \$ignore_perl_version, - 'debug=s' => \%debug, - 'test-only=s' => \$tst_only, - 'codespell!' => \$codespell, - 'codespellfile=s' => \$codespellfile, - 'typedefsfile=s' => \$typedefsfile, - 'color=s' => \$color, - 'no-color' => \$color, #keep old behaviors of -nocolor - 'nocolor' => \$color, #keep old behaviors of -nocolor - 'kconfig-prefix=s' => \${CONFIG_}, - 'h|help' => \$help, - 'version' => \$help -) or help(1); - -help(0) if ($help); - -list_types(0) if ($list_types); - -$fix = 1 if ($fix_inplace); -$check_orig = $check; - -die "$P: --git cannot be used with --file or --fix\n" if ($git && ($file || $fix)); - -my $exit = 0; - -my $perl_version_ok = 1; -if ($^V && $^V lt $minimum_perl_version) { - $perl_version_ok = 0; - printf "$P: requires at least perl version %vd\n", $minimum_perl_version; - exit(1) if (!$ignore_perl_version); -} - -#if no filenames are given, push '-' to read patch from stdin -if ($#ARGV < 0) { - push(@ARGV, '-'); -} - -if ($color =~ /^[01]$/) { - $color = !$color; -} elsif ($color =~ /^always$/i) { - $color = 1; -} elsif ($color =~ /^never$/i) { - $color = 0; -} elsif ($color =~ /^auto$/i) { - $color = (-t STDOUT); -} else { - die "$P: Invalid color mode: $color\n"; -} - -# skip TAB size 1 to avoid additional checks on $tabsize - 1 -die "$P: Invalid TAB size: $tabsize\n" if ($tabsize < 2); - -sub hash_save_array_words { - my ($hashRef, $arrayRef) = @_; - - my @array = split(/,/, join(',', @$arrayRef)); - foreach my $word (@array) { - $word =~ s/\s*\n?$//g; - $word =~ s/^\s*//g; - $word =~ s/\s+/ /g; - $word =~ tr/[a-z]/[A-Z]/; - - next if ($word =~ m/^\s*#/); - next if ($word =~ m/^\s*$/); - - $hashRef->{$word}++; - } -} - -sub hash_show_words { - my ($hashRef, $prefix) = @_; - - if (keys %$hashRef) { - print "\nNOTE: $prefix message types:"; - foreach my $word (sort keys %$hashRef) { - print " $word"; - } - print "\n"; - } -} - -hash_save_array_words(\%ignore_type, \@ignore); -hash_save_array_words(\%use_type, \@use); - -my $dbg_values = 0; -my $dbg_possible = 0; -my $dbg_type = 0; -my $dbg_attr = 0; -for my $key (keys %debug) { - ## no critic - eval "\${dbg_$key} = '$debug{$key}';"; - die "$@" if ($@); -} - -my $rpt_cleaners = 0; - -if ($terse) { - $emacs = 1; - $quiet++; -} - -if ($tree) { - if (defined $root) { - if (!top_of_kernel_tree($root)) { - die "$P: $root: --root does not point at a valid tree\n"; - } - } else { - if (top_of_kernel_tree('.')) { - $root = '.'; - } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && - top_of_kernel_tree($1)) { - $root = $1; - } - } - - if (!defined $root) { - print "Must be run from the top-level dir. of a kernel tree\n"; - exit(2); - } -} - -my $emitted_corrupt = 0; - -our $Ident = qr{ - [A-Za-z_][A-Za-z\d_]* - (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* - }x; -our $Storage = qr{extern|static|asmlinkage}; -our $Sparse = qr{ - __user| - __kernel| - __force| - __iomem| - __must_check| - __kprobes| - __ref| - __refconst| - __refdata| - __rcu| - __private - }x; -our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)}; -our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)}; -our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)}; -our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)}; -our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; - -# Notes to $Attribute: -# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check -our $Attribute = qr{ - const| - __percpu| - __nocast| - __safe| - __bitwise| - __packed__| - __packed2__| - __naked| - __maybe_unused| - __always_unused| - __noreturn| - __used| - __cold| - __pure| - __noclone| - __deprecated| - __read_mostly| - __ro_after_init| - __kprobes| - $InitAttribute| - ____cacheline_aligned| - ____cacheline_aligned_in_smp| - ____cacheline_internodealigned_in_smp| - __weak - }x; -our $Modifier; -our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__}; -our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; -our $Lval = qr{$Ident(?:$Member)*}; - -our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; -our $Binary = qr{(?i)0b[01]+$Int_type?}; -our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; -our $Int = qr{[0-9]+$Int_type?}; -our $Octal = qr{0[0-7]+$Int_type?}; -our $String = qr{"[X\t]*"}; -our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; -our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; -our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; -our $Float = qr{$Float_hex|$Float_dec|$Float_int}; -our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int}; -our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; -our $Compare = qr{<=|>=|==|!=|<|(?}; -our $Arithmetic = qr{\+|-|\*|\/|%}; -our $Operators = qr{ - <=|>=|==|!=| - =>|->|<<|>>|<|>|!|~| - &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic - }x; - -our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; - -our $BasicType; -our $NonptrType; -our $NonptrTypeMisordered; -our $NonptrTypeWithAttr; -our $Type; -our $TypeMisordered; -our $Declare; -our $DeclareMisordered; - -our $NON_ASCII_UTF8 = qr{ - [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs - | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte - | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates - | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 - | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 - | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 -}x; - -our $UTF8 = qr{ - [\x09\x0A\x0D\x20-\x7E] # ASCII - | $NON_ASCII_UTF8 -}x; - -our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t}; -our $typeOtherOSTypedefs = qr{(?x: - u_(?:char|short|int|long) | # bsd - u(?:nchar|short|int|long) # sysv -)}; -our $typeKernelTypedefs = qr{(?x: - (?:__)?(?:u|s|be|le)(?:8|16|32|64)| - atomic_t -)}; -our $typeTypedefs = qr{(?x: - $typeC99Typedefs\b| - $typeOtherOSTypedefs\b| - $typeKernelTypedefs\b -)}; - -our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; - -our $logFunctions = qr{(?x: - printk(?:_ratelimited|_once|_deferred_once|_deferred|)| - (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| - TP_printk| - WARN(?:_RATELIMIT|_ONCE|)| - panic| - MODULE_[A-Z_]+| - seq_vprintf|seq_printf|seq_puts -)}; - -our $allocFunctions = qr{(?x: - (?:(?:devm_)? - (?:kv|k|v)[czm]alloc(?:_node|_array)? | - kstrdup(?:_const)? | - kmemdup(?:_nul)?) | - (?:\w+)?alloc_skb(?:_ip_align)? | - # dev_alloc_skb/netdev_alloc_skb, et al - dma_alloc_coherent -)}; - -our $signature_tags = qr{(?xi: - Signed-off-by:| - Co-developed-by:| - Acked-by:| - Tested-by:| - Reviewed-by:| - Reported-by:| - Suggested-by:| - To:| - Cc: -)}; - -our @typeListMisordered = ( - qr{char\s+(?:un)?signed}, - qr{int\s+(?:(?:un)?signed\s+)?short\s}, - qr{int\s+short(?:\s+(?:un)?signed)}, - qr{short\s+int(?:\s+(?:un)?signed)}, - qr{(?:un)?signed\s+int\s+short}, - qr{short\s+(?:un)?signed}, - qr{long\s+int\s+(?:un)?signed}, - qr{int\s+long\s+(?:un)?signed}, - qr{long\s+(?:un)?signed\s+int}, - qr{int\s+(?:un)?signed\s+long}, - qr{int\s+(?:un)?signed}, - qr{int\s+long\s+long\s+(?:un)?signed}, - qr{long\s+long\s+int\s+(?:un)?signed}, - qr{long\s+long\s+(?:un)?signed\s+int}, - qr{long\s+long\s+(?:un)?signed}, - qr{long\s+(?:un)?signed}, -); - -our @typeList = ( - qr{void}, - qr{(?:(?:un)?signed\s+)?char}, - qr{(?:(?:un)?signed\s+)?short\s+int}, - qr{(?:(?:un)?signed\s+)?short}, - qr{(?:(?:un)?signed\s+)?int}, - qr{(?:(?:un)?signed\s+)?long\s+int}, - qr{(?:(?:un)?signed\s+)?long\s+long\s+int}, - qr{(?:(?:un)?signed\s+)?long\s+long}, - qr{(?:(?:un)?signed\s+)?long}, - qr{(?:un)?signed}, - qr{float}, - qr{double}, - qr{bool}, - qr{struct\s+$Ident}, - qr{union\s+$Ident}, - qr{enum\s+$Ident}, - qr{${Ident}_t}, - qr{${Ident}_handler}, - qr{${Ident}_handler_fn}, - @typeListMisordered, -); - -our $C90_int_types = qr{(?x: - long\s+long\s+int\s+(?:un)?signed| - long\s+long\s+(?:un)?signed\s+int| - long\s+long\s+(?:un)?signed| - (?:(?:un)?signed\s+)?long\s+long\s+int| - (?:(?:un)?signed\s+)?long\s+long| - int\s+long\s+long\s+(?:un)?signed| - int\s+(?:(?:un)?signed\s+)?long\s+long| - - long\s+int\s+(?:un)?signed| - long\s+(?:un)?signed\s+int| - long\s+(?:un)?signed| - (?:(?:un)?signed\s+)?long\s+int| - (?:(?:un)?signed\s+)?long| - int\s+long\s+(?:un)?signed| - int\s+(?:(?:un)?signed\s+)?long| - - int\s+(?:un)?signed| - (?:(?:un)?signed\s+)?int -)}; - -our @typeListFile = (); -our @typeListWithAttr = ( - @typeList, - qr{struct\s+$InitAttribute\s+$Ident}, - qr{union\s+$InitAttribute\s+$Ident}, -); - -our @modifierList = ( - qr{fastcall}, -); -our @modifierListFile = (); - -our @mode_permission_funcs = ( - ["module_param", 3], - ["module_param_(?:array|named|string)", 4], - ["module_param_array_named", 5], - ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2], - ["proc_create(?:_data|)", 2], - ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2], - ["IIO_DEV_ATTR_[A-Z_]+", 1], - ["SENSOR_(?:DEVICE_|)ATTR_2", 2], - ["SENSOR_TEMPLATE(?:_2|)", 3], - ["__ATTR", 2], -); - -my $word_pattern = '\b[A-Z]?[a-z]{2,}\b'; - -#Create a search pattern for all these functions to speed up a loop below -our $mode_perms_search = ""; -foreach my $entry (@mode_permission_funcs) { - $mode_perms_search .= '|' if ($mode_perms_search ne ""); - $mode_perms_search .= $entry->[0]; -} -$mode_perms_search = "(?:${mode_perms_search})"; - -our %deprecated_apis = ( - "synchronize_rcu_bh" => "synchronize_rcu", - "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", - "call_rcu_bh" => "call_rcu", - "rcu_barrier_bh" => "rcu_barrier", - "synchronize_sched" => "synchronize_rcu", - "synchronize_sched_expedited" => "synchronize_rcu_expedited", - "call_rcu_sched" => "call_rcu", - "rcu_barrier_sched" => "rcu_barrier", - "get_state_synchronize_sched" => "get_state_synchronize_rcu", - "cond_synchronize_sched" => "cond_synchronize_rcu", -); - -#Create a search pattern for all these strings to speed up a loop below -our $deprecated_apis_search = ""; -foreach my $entry (keys %deprecated_apis) { - $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); - $deprecated_apis_search .= $entry; -} -$deprecated_apis_search = "(?:${deprecated_apis_search})"; - -our $mode_perms_world_writable = qr{ - S_IWUGO | - S_IWOTH | - S_IRWXUGO | - S_IALLUGO | - 0[0-7][0-7][2367] -}x; - -our %mode_permission_string_types = ( - "S_IRWXU" => 0700, - "S_IRUSR" => 0400, - "S_IWUSR" => 0200, - "S_IXUSR" => 0100, - "S_IRWXG" => 0070, - "S_IRGRP" => 0040, - "S_IWGRP" => 0020, - "S_IXGRP" => 0010, - "S_IRWXO" => 0007, - "S_IROTH" => 0004, - "S_IWOTH" => 0002, - "S_IXOTH" => 0001, - "S_IRWXUGO" => 0777, - "S_IRUGO" => 0444, - "S_IWUGO" => 0222, - "S_IXUGO" => 0111, -); - -#Create a search pattern for all these strings to speed up a loop below -our $mode_perms_string_search = ""; -foreach my $entry (keys %mode_permission_string_types) { - $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); - $mode_perms_string_search .= $entry; -} -our $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; -our $multi_mode_perms_string_search = qr{ - ${single_mode_perms_string_search} - (?:\s*\|\s*${single_mode_perms_string_search})* -}x; - -sub perms_to_octal { - my ($string) = @_; - - return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); - - my $val = ""; - my $oval = ""; - my $to = 0; - my $curpos = 0; - my $lastpos = 0; - while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { - $curpos = pos($string); - my $match = $2; - my $omatch = $1; - last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); - $lastpos = $curpos; - $to |= $mode_permission_string_types{$match}; - $val .= '\s*\|\s*' if ($val ne ""); - $val .= $match; - $oval .= $omatch; - } - $oval =~ s/^\s*\|\s*//; - $oval =~ s/\s*\|\s*$//; - return sprintf("%04o", $to); -} - -our $allowed_asm_includes = qr{(?x: - irq| - memory| - time| - reboot -)}; -# memory.h: ARM has a custom one - -# Load common spelling mistakes and build regular expression list. -my $misspellings; -my %spelling_fix; - -if (open(my $spelling, '<', $spelling_file)) { - while (<$spelling>) { - my $line = $_; - - $line =~ s/\s*\n?$//g; - $line =~ s/^\s*//g; - - next if ($line =~ m/^\s*#/); - next if ($line =~ m/^\s*$/); - - my ($suspect, $fix) = split(/\|\|/, $line); - - $spelling_fix{$suspect} = $fix; - } - close($spelling); -} else { - warn "No typos will be found - file '$spelling_file': $!\n"; -} - -if ($codespell) { - if (open(my $spelling, '<', $codespellfile)) { - while (<$spelling>) { - my $line = $_; - - $line =~ s/\s*\n?$//g; - $line =~ s/^\s*//g; - - next if ($line =~ m/^\s*#/); - next if ($line =~ m/^\s*$/); - next if ($line =~ m/, disabled/i); - - $line =~ s/,.*$//; - - my ($suspect, $fix) = split(/->/, $line); - - $spelling_fix{$suspect} = $fix; - } - close($spelling); - } else { - warn "No codespell typos will be found - file '$codespellfile': $!\n"; - } -} - -$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix; - -sub read_words { - my ($wordsRef, $file) = @_; - - if (open(my $words, '<', $file)) { - while (<$words>) { - my $line = $_; - - $line =~ s/\s*\n?$//g; - $line =~ s/^\s*//g; - - next if ($line =~ m/^\s*#/); - next if ($line =~ m/^\s*$/); - if ($line =~ /\s/) { - print("$file: '$line' invalid - ignored\n"); - next; - } - - $$wordsRef .= '|' if (defined $$wordsRef); - $$wordsRef .= $line; - } - close($file); - return 1; - } - - return 0; -} - -my $const_structs; -if (show_type("CONST_STRUCT")) { - read_words(\$const_structs, $conststructsfile) - or warn "No structs that should be const will be found - file '$conststructsfile': $!\n"; -} - -if (defined($typedefsfile)) { - my $typeOtherTypedefs; - read_words(\$typeOtherTypedefs, $typedefsfile) - or warn "No additional types will be considered - file '$typedefsfile': $!\n"; - $typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs); -} - -sub build_types { - my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)"; - my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)"; - my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)"; - my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)"; - $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; - $BasicType = qr{ - (?:$typeTypedefs\b)| - (?:${all}\b) - }x; - $NonptrType = qr{ - (?:$Modifier\s+|const\s+)* - (?: - (?:typeof|__typeof__)\s*\([^\)]*\)| - (?:$typeTypedefs\b)| - (?:${all}\b) - ) - (?:\s+$Modifier|\s+const)* - }x; - $NonptrTypeMisordered = qr{ - (?:$Modifier\s+|const\s+)* - (?: - (?:${Misordered}\b) - ) - (?:\s+$Modifier|\s+const)* - }x; - $NonptrTypeWithAttr = qr{ - (?:$Modifier\s+|const\s+)* - (?: - (?:typeof|__typeof__)\s*\([^\)]*\)| - (?:$typeTypedefs\b)| - (?:${allWithAttr}\b) - ) - (?:\s+$Modifier|\s+const)* - }x; - $Type = qr{ - $NonptrType - (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} - (?:\s+$Inline|\s+$Modifier)* - }x; - $TypeMisordered = qr{ - $NonptrTypeMisordered - (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4} - (?:\s+$Inline|\s+$Modifier)* - }x; - $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type}; - $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered}; -} -build_types(); - -our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; - -# Using $balanced_parens, $LvalOrFunc, or $FuncArg -# requires at least perl version v5.10.0 -# Any use must be runtime checked with $^V - -our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; -our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*}; -our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)}; - -our $declaration_macros = qr{(?x: - (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| - (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(| - (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\( -)}; - -sub deparenthesize { - my ($string) = @_; - return "" if (!defined($string)); - - while ($string =~ /^\s*\(.*\)\s*$/) { - $string =~ s@^\s*\(\s*@@; - $string =~ s@\s*\)\s*$@@; - } - - $string =~ s@\s+@ @g; - - return $string; -} - -sub seed_camelcase_file { - my ($file) = @_; - - return if (!(-f $file)); - - local $/; - - open(my $include_file, '<', "$file") - or warn "$P: Can't read '$file' $!\n"; - my $text = <$include_file>; - close($include_file); - - my @lines = split('\n', $text); - - foreach my $line (@lines) { - next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/); - if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) { - $camelcase{$1} = 1; - } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) { - $camelcase{$1} = 1; - } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) { - $camelcase{$1} = 1; - } - } -} - -our %maintained_status = (); - -sub is_maintained_obsolete { - my ($filename) = @_; - - return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl")); - - if (!exists($maintained_status{$filename})) { - $maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`; - } - - return $maintained_status{$filename} =~ /obsolete/i; -} - -sub is_SPDX_License_valid { - my ($license) = @_; - - return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$gitroot")); - - my $root_path = abs_path($root); - my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; - return 0 if ($status ne ""); - return 1; -} - -my $camelcase_seeded = 0; -sub seed_camelcase_includes { - return if ($camelcase_seeded); - - my $files; - my $camelcase_cache = ""; - my @include_files = (); - - $camelcase_seeded = 1; - - if (-e "$gitroot") { - my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; - chomp $git_last_include_commit; - $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; - } else { - my $last_mod_date = 0; - $files = `find $root/include -name "*.h"`; - @include_files = split('\n', $files); - foreach my $file (@include_files) { - my $date = POSIX::strftime("%Y%m%d%H%M", - localtime((stat $file)[9])); - $last_mod_date = $date if ($last_mod_date < $date); - } - $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date"; - } - - if ($camelcase_cache ne "" && -f $camelcase_cache) { - open(my $camelcase_file, '<', "$camelcase_cache") - or warn "$P: Can't read '$camelcase_cache' $!\n"; - while (<$camelcase_file>) { - chomp; - $camelcase{$_} = 1; - } - close($camelcase_file); - - return; - } - - if (-e "$gitroot") { - $files = `${git_command} ls-files "include/*.h"`; - @include_files = split('\n', $files); - } - - foreach my $file (@include_files) { - seed_camelcase_file($file); - } - - if ($camelcase_cache ne "") { - unlink glob ".checkpatch-camelcase.*"; - open(my $camelcase_file, '>', "$camelcase_cache") - or warn "$P: Can't write '$camelcase_cache' $!\n"; - foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) { - print $camelcase_file ("$_\n"); - } - close($camelcase_file); - } -} - -sub git_is_single_file { - my ($filename) = @_; - - return 0 if ((which("git") eq "") || !(-e "$gitroot")); - - my $output = `${git_command} ls-files -- $filename 2>/dev/null`; - my $count = $output =~ tr/\n//; - return $count eq 1 && $output =~ m{^${filename}$}; -} - -sub git_commit_info { - my ($commit, $id, $desc) = @_; - - return ($id, $desc) if ((which("git") eq "") || !(-e "$gitroot")); - - my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; - $output =~ s/^\s*//gm; - my @lines = split("\n", $output); - - return ($id, $desc) if ($#lines < 0); - - if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { -# Maybe one day convert this block of bash into something that returns -# all matching commit ids, but it's very slow... -# -# echo "checking commits $1..." -# git rev-list --remotes | grep -i "^$1" | -# while read line ; do -# git log --format='%H %s' -1 $line | -# echo "commit $(cut -c 1-12,41-)" -# done - } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { - $id = undef; - } else { - $id = substr($lines[0], 0, 12); - $desc = substr($lines[0], 41); - } - - return ($id, $desc); -} - -$chk_signoff = 0 if ($file); - -my @rawlines = (); -my @lines = (); -my @fixed = (); -my @fixed_inserted = (); -my @fixed_deleted = (); -my $fixlinenr = -1; - -# If input is git commits, extract all commits from the commit expressions. -# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'. -die "$P: No git repository found\n" if ($git && !-e "$gitroot"); - -if ($git) { - my @commits = (); - foreach my $commit_expr (@ARGV) { - my $git_range; - if ($commit_expr =~ m/^(.*)-(\d+)$/) { - $git_range = "-$2 $1"; - } elsif ($commit_expr =~ m/\.\./) { - $git_range = "$commit_expr"; - } else { - $git_range = "-1 $commit_expr"; - } - my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; - foreach my $line (split(/\n/, $lines)) { - $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; - next if (!defined($1) || !defined($2)); - my $sha1 = $1; - my $subject = $2; - unshift(@commits, $sha1); - $git_commits{$sha1} = $subject; - } - } - die "$P: no git commits after extraction!\n" if (@commits == 0); - @ARGV = @commits; -} - -my $vname; -$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; -for my $filename (@ARGV) { - my $FILE; - my $is_git_file = git_is_single_file($filename); - my $oldfile = $file; - $file = 1 if ($is_git_file); - if ($git) { - open($FILE, '-|', "git format-patch -M --stdout -1 $filename") || - die "$P: $filename: git format-patch failed - $!\n"; - } elsif ($file) { - open($FILE, '-|', "diff -u /dev/null $filename") || - die "$P: $filename: diff failed - $!\n"; - } elsif ($filename eq '-') { - open($FILE, '<&STDIN'); - } else { - open($FILE, '<', "$filename") || - die "$P: $filename: open failed - $!\n"; - } - if ($filename eq '-') { - $vname = 'Your patch'; - } elsif ($git) { - $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")'; - } else { - $vname = $filename; - } - while (<$FILE>) { - chomp; - push(@rawlines, $_); - $vname = qq("$1") if ($filename eq '-' && $_ =~ m/^Subject:\s+(.+)/i); - } - close($FILE); - - if ($#ARGV > 0 && $quiet == 0) { - print '-' x length($vname) . "\n"; - print "$vname\n"; - print '-' x length($vname) . "\n"; - } - - if (!process($filename)) { - $exit = 1; - } - @rawlines = (); - @lines = (); - @fixed = (); - @fixed_inserted = (); - @fixed_deleted = (); - $fixlinenr = -1; - @modifierListFile = (); - @typeListFile = (); - build_types(); - $file = $oldfile if ($is_git_file); -} - -if (!$quiet) { - hash_show_words(\%use_type, "Used"); - hash_show_words(\%ignore_type, "Ignored"); - - if (!$perl_version_ok) { - print << "EOM" - -NOTE: perl $^V is not modern enough to detect all possible issues. - An upgrade to at least perl $minimum_perl_version is suggested. -EOM - } - if ($exit) { - print << "EOM" - -NOTE: If any of the errors are false positives, please report - them to the maintainer, see CHECKPATCH in MAINTAINERS. -EOM - } -} - -exit($exit); - -sub top_of_kernel_tree { - my ($root) = @_; - - my @tree_check = ( - "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", - "README", "Documentation", "arch", "include", "drivers", - "fs", "init", "ipc", "kernel", "lib", "scripts", - ); - - foreach my $check (@tree_check) { - if (! -e $root . '/' . $check) { - return 0; - } - } - return 1; -} - -sub parse_email { - my ($formatted_email) = @_; - - my $name = ""; - my $name_comment = ""; - my $address = ""; - my $comment = ""; - - if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { - $name = $1; - $address = $2; - $comment = $3 if defined $3; - } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { - $address = $1; - $comment = $2 if defined $2; - } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { - $address = $1; - $comment = $2 if defined $2; - $formatted_email =~ s/\Q$address\E.*$//; - $name = $formatted_email; - $name = trim($name); - $name =~ s/^\"|\"$//g; - # If there's a name left after stripping spaces and - # leading quotes, and the address doesn't have both - # leading and trailing angle brackets, the address - # is invalid. ie: - # "joe smith joe@smith.com" bad - # "joe smith ]+>$/) { - $name = ""; - $address = ""; - $comment = ""; - } - } - - $comment = trim($comment); - $name = trim($name); - $name =~ s/^\"|\"$//g; - if ($name =~ s/(\s*\([^\)]+\))\s*//) { - $name_comment = trim($1); - } - $address = trim($address); - $address =~ s/^\<|\>$//g; - - if ($name =~ /[^\w \-]/i) { ##has "must quote" chars - $name =~ s/(?"; - } - $formatted_email .= "$comment"; - return $formatted_email; -} - -sub reformat_email { - my ($email) = @_; - - my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); - return format_email($email_name, $name_comment, $email_address, $comment); -} - -sub same_email_addresses { - my ($email1, $email2, $match_comment) = @_; - - my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1); - my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2); - - if ($match_comment != 1) { - return $email1_name eq $email2_name && - $email1_address eq $email2_address; - } - return $email1_name eq $email2_name && - $email1_address eq $email2_address && - $name1_comment eq $name2_comment && - $comment1 eq $comment2; -} - -sub which { - my ($bin) = @_; - - foreach my $path (split(/:/, $ENV{PATH})) { - if (-e "$path/$bin") { - return "$path/$bin"; - } - } - - return ""; -} - -sub which_conf { - my ($conf) = @_; - - foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { - if (-e "$path/$conf") { - return "$path/$conf"; - } - } - - return ""; -} - -sub expand_tabs { - my ($str) = @_; - - my $res = ''; - my $n = 0; - for my $c (split(//, $str)) { - if ($c eq "\t") { - $res .= ' '; - $n++; - for (; ($n % $tabsize) != 0; $n++) { - $res .= ' '; - } - next; - } - $res .= $c; - $n++; - } - - return $res; -} -sub copy_spacing { - (my $res = shift) =~ tr/\t/ /c; - return $res; -} - -sub line_stats { - my ($line) = @_; - - # Drop the diff line leader and expand tabs - $line =~ s/^.//; - $line = expand_tabs($line); - - # Pick the indent from the front of the line. - my ($white) = ($line =~ /^(\s*)/); - - return (length($line), length($white)); -} - -my $sanitise_quote = ''; - -sub sanitise_line_reset { - my ($in_comment) = @_; - - if ($in_comment) { - $sanitise_quote = '*/'; - } else { - $sanitise_quote = ''; - } -} -sub sanitise_line { - my ($line) = @_; - - my $res = ''; - my $l = ''; - - my $qlen = 0; - my $off = 0; - my $c; - - # Always copy over the diff marker. - $res = substr($line, 0, 1); - - for ($off = 1; $off < length($line); $off++) { - $c = substr($line, $off, 1); - - # Comments we are whacking completely including the begin - # and end, all to $;. - if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { - $sanitise_quote = '*/'; - - substr($res, $off, 2, "$;$;"); - $off++; - next; - } - if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { - $sanitise_quote = ''; - substr($res, $off, 2, "$;$;"); - $off++; - next; - } - if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { - $sanitise_quote = '//'; - - substr($res, $off, 2, $sanitise_quote); - $off++; - next; - } - - # A \ in a string means ignore the next character. - if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && - $c eq "\\") { - substr($res, $off, 2, 'XX'); - $off++; - next; - } - # Regular quotes. - if ($c eq "'" || $c eq '"') { - if ($sanitise_quote eq '') { - $sanitise_quote = $c; - - substr($res, $off, 1, $c); - next; - } elsif ($sanitise_quote eq $c) { - $sanitise_quote = ''; - } - } - - #print "c<$c> SQ<$sanitise_quote>\n"; - if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { - substr($res, $off, 1, $;); - } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { - substr($res, $off, 1, $;); - } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { - substr($res, $off, 1, 'X'); - } else { - substr($res, $off, 1, $c); - } - } - - if ($sanitise_quote eq '//') { - $sanitise_quote = ''; - } - - # The pathname on a #include may be surrounded by '<' and '>'. - if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { - my $clean = 'X' x length($1); - $res =~ s@\<.*\>@<$clean>@; - - # The whole of a #error is a string. - } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { - my $clean = 'X' x length($1); - $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; - } - - if ($allow_c99_comments && $res =~ m@(//.*$)@) { - my $match = $1; - $res =~ s/\Q$match\E/"$;" x length($match)/e; - } - - return $res; -} - -sub get_quoted_string { - my ($line, $rawline) = @_; - - return "" if (!defined($line) || !defined($rawline)); - return "" if ($line !~ m/($String)/g); - return substr($rawline, $-[0], $+[0] - $-[0]); -} - -sub ctx_statement_block { - my ($linenr, $remain, $off) = @_; - my $line = $linenr - 1; - my $blk = ''; - my $soff = $off; - my $coff = $off - 1; - my $coff_set = 0; - - my $loff = 0; - - my $type = ''; - my $level = 0; - my @stack = (); - my $p; - my $c; - my $len = 0; - - my $remainder; - while (1) { - @stack = (['', 0]) if ($#stack == -1); - - #warn "CSB: blk<$blk> remain<$remain>\n"; - # If we are about to drop off the end, pull in more - # context. - if ($off >= $len) { - for (; $remain > 0; $line++) { - last if (!defined $lines[$line]); - next if ($lines[$line] =~ /^-/); - $remain--; - $loff = $len; - $blk .= $lines[$line] . "\n"; - $len = length($blk); - $line++; - last; - } - # Bail if there is no further context. - #warn "CSB: blk<$blk> off<$off> len<$len>\n"; - if ($off >= $len) { - last; - } - if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { - $level++; - $type = '#'; - } - } - $p = $c; - $c = substr($blk, $off, 1); - $remainder = substr($blk, $off); - - #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; - - # Handle nested #if/#else. - if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { - push(@stack, [ $type, $level ]); - } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { - ($type, $level) = @{$stack[$#stack - 1]}; - } elsif ($remainder =~ /^#\s*endif\b/) { - ($type, $level) = @{pop(@stack)}; - } - - # Statement ends at the ';' or a close '}' at the - # outermost level. - if ($level == 0 && $c eq ';') { - last; - } - - # An else is really a conditional as long as its not else if - if ($level == 0 && $coff_set == 0 && - (!defined($p) || $p =~ /(?:\s|\}|\+)/) && - $remainder =~ /^(else)(?:\s|{)/ && - $remainder !~ /^else\s+if\b/) { - $coff = $off + length($1) - 1; - $coff_set = 1; - #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; - #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; - } - - if (($type eq '' || $type eq '(') && $c eq '(') { - $level++; - $type = '('; - } - if ($type eq '(' && $c eq ')') { - $level--; - $type = ($level != 0)? '(' : ''; - - if ($level == 0 && $coff < $soff) { - $coff = $off; - $coff_set = 1; - #warn "CSB: mark coff<$coff>\n"; - } - } - if (($type eq '' || $type eq '{') && $c eq '{') { - $level++; - $type = '{'; - } - if ($type eq '{' && $c eq '}') { - $level--; - $type = ($level != 0)? '{' : ''; - - if ($level == 0) { - if (substr($blk, $off + 1, 1) eq ';') { - $off++; - } - last; - } - } - # Preprocessor commands end at the newline unless escaped. - if ($type eq '#' && $c eq "\n" && $p ne "\\") { - $level--; - $type = ''; - $off++; - last; - } - $off++; - } - # We are truly at the end, so shuffle to the next line. - if ($off == $len) { - $loff = $len + 1; - $line++; - $remain--; - } - - my $statement = substr($blk, $soff, $off - $soff + 1); - my $condition = substr($blk, $soff, $coff - $soff + 1); - - #warn "STATEMENT<$statement>\n"; - #warn "CONDITION<$condition>\n"; - - #print "coff<$coff> soff<$off> loff<$loff>\n"; - - return ($statement, $condition, - $line, $remain + 1, $off - $loff + 1, $level); -} - -sub statement_lines { - my ($stmt) = @_; - - # Strip the diff line prefixes and rip blank lines at start and end. - $stmt =~ s/(^|\n)./$1/g; - $stmt =~ s/^\s*//; - $stmt =~ s/\s*$//; - - my @stmt_lines = ($stmt =~ /\n/g); - - return $#stmt_lines + 2; -} - -sub statement_rawlines { - my ($stmt) = @_; - - my @stmt_lines = ($stmt =~ /\n/g); - - return $#stmt_lines + 2; -} - -sub statement_block_size { - my ($stmt) = @_; - - $stmt =~ s/(^|\n)./$1/g; - $stmt =~ s/^\s*{//; - $stmt =~ s/}\s*$//; - $stmt =~ s/^\s*//; - $stmt =~ s/\s*$//; - - my @stmt_lines = ($stmt =~ /\n/g); - my @stmt_statements = ($stmt =~ /;/g); - - my $stmt_lines = $#stmt_lines + 2; - my $stmt_statements = $#stmt_statements + 1; - - if ($stmt_lines > $stmt_statements) { - return $stmt_lines; - } else { - return $stmt_statements; - } -} - -sub ctx_statement_full { - my ($linenr, $remain, $off) = @_; - my ($statement, $condition, $level); - - my (@chunks); - - # Grab the first conditional/block pair. - ($statement, $condition, $linenr, $remain, $off, $level) = - ctx_statement_block($linenr, $remain, $off); - #print "F: c<$condition> s<$statement> remain<$remain>\n"; - push(@chunks, [ $condition, $statement ]); - if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { - return ($level, $linenr, @chunks); - } - - # Pull in the following conditional/block pairs and see if they - # could continue the statement. - for (;;) { - ($statement, $condition, $linenr, $remain, $off, $level) = - ctx_statement_block($linenr, $remain, $off); - #print "C: c<$condition> s<$statement> remain<$remain>\n"; - last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); - #print "C: push\n"; - push(@chunks, [ $condition, $statement ]); - } - - return ($level, $linenr, @chunks); -} - -sub ctx_block_get { - my ($linenr, $remain, $outer, $open, $close, $off) = @_; - my $line; - my $start = $linenr - 1; - my $blk = ''; - my @o; - my @c; - my @res = (); - - my $level = 0; - my @stack = ($level); - for ($line = $start; $remain > 0; $line++) { - next if ($rawlines[$line] =~ /^-/); - $remain--; - - $blk .= $rawlines[$line]; - - # Handle nested #if/#else. - if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { - push(@stack, $level); - } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { - $level = $stack[$#stack - 1]; - } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { - $level = pop(@stack); - } - - foreach my $c (split(//, $lines[$line])) { - ##print "C<$c>L<$level><$open$close>O<$off>\n"; - if ($off > 0) { - $off--; - next; - } - - if ($c eq $close && $level > 0) { - $level--; - last if ($level == 0); - } elsif ($c eq $open) { - $level++; - } - } - - if (!$outer || $level <= 1) { - push(@res, $rawlines[$line]); - } - - last if ($level == 0); - } - - return ($level, @res); -} -sub ctx_block_outer { - my ($linenr, $remain) = @_; - - my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); - return @r; -} -sub ctx_block { - my ($linenr, $remain) = @_; - - my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); - return @r; -} -sub ctx_statement { - my ($linenr, $remain, $off) = @_; - - my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); - return @r; -} -sub ctx_block_level { - my ($linenr, $remain) = @_; - - return ctx_block_get($linenr, $remain, 0, '{', '}', 0); -} -sub ctx_statement_level { - my ($linenr, $remain, $off) = @_; - - return ctx_block_get($linenr, $remain, 0, '(', ')', $off); -} - -sub ctx_locate_comment { - my ($first_line, $end_line) = @_; - - # If c99 comment on the current line, or the line before or after - my ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\+.*(//.*$)@); - return $current_comment if (defined $current_comment); - ($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\+ ].*(//.*$)@); - return $current_comment if (defined $current_comment); - ($current_comment) = ($rawlines[$end_line] =~ m@^[\+ ].*(//.*$)@); - return $current_comment if (defined $current_comment); - - # Catch a comment on the end of the line itself. - ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); - return $current_comment if (defined $current_comment); - - # Look through the context and try and figure out if there is a - # comment. - my $in_comment = 0; - $current_comment = ''; - for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { - my $line = $rawlines[$linenr - 1]; - #warn " $line\n"; - if ($linenr == $first_line and $line =~ m@^.\s*\*@) { - $in_comment = 1; - } - if ($line =~ m@/\*@) { - $in_comment = 1; - } - if (!$in_comment && $current_comment ne '') { - $current_comment = ''; - } - $current_comment .= $line . "\n" if ($in_comment); - if ($line =~ m@\*/@) { - $in_comment = 0; - } - } - - chomp($current_comment); - return($current_comment); -} -sub ctx_has_comment { - my ($first_line, $end_line) = @_; - my $cmt = ctx_locate_comment($first_line, $end_line); - - ##print "LINE: $rawlines[$end_line - 1 ]\n"; - ##print "CMMT: $cmt\n"; - - return ($cmt ne ''); -} - -sub raw_line { - my ($linenr, $cnt) = @_; - - my $offset = $linenr - 1; - $cnt++; - - my $line; - while ($cnt) { - $line = $rawlines[$offset++]; - next if (defined($line) && $line =~ /^-/); - $cnt--; - } - - return $line; -} - -sub get_stat_real { - my ($linenr, $lc) = @_; - - my $stat_real = raw_line($linenr, 0); - for (my $count = $linenr + 1; $count <= $lc; $count++) { - $stat_real = $stat_real . "\n" . raw_line($count, 0); - } - - return $stat_real; -} - -sub get_stat_here { - my ($linenr, $cnt, $here) = @_; - - my $herectx = $here . "\n"; - for (my $n = 0; $n < $cnt; $n++) { - $herectx .= raw_line($linenr, $n) . "\n"; - } - - return $herectx; -} - -sub cat_vet { - my ($vet) = @_; - my ($res, $coded); - - $res = ''; - while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { - $res .= $1; - if ($2 ne '') { - $coded = sprintf("^%c", unpack('C', $2) + 64); - $res .= $coded; - } - } - $res =~ s/$/\$/; - - return $res; -} - -my $av_preprocessor = 0; -my $av_pending; -my @av_paren_type; -my $av_pend_colon; - -sub annotate_reset { - $av_preprocessor = 0; - $av_pending = '_'; - @av_paren_type = ('E'); - $av_pend_colon = 'O'; -} - -sub annotate_values { - my ($stream, $type) = @_; - - my $res; - my $var = '_' x length($stream); - my $cur = $stream; - - print "$stream\n" if ($dbg_values > 1); - - while (length($cur)) { - @av_paren_type = ('E') if ($#av_paren_type < 0); - print " <" . join('', @av_paren_type) . - "> <$type> <$av_pending>" if ($dbg_values > 1); - if ($cur =~ /^(\s+)/o) { - print "WS($1)\n" if ($dbg_values > 1); - if ($1 =~ /\n/ && $av_preprocessor) { - $type = pop(@av_paren_type); - $av_preprocessor = 0; - } - - } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { - print "CAST($1)\n" if ($dbg_values > 1); - push(@av_paren_type, $type); - $type = 'c'; - - } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { - print "DECLARE($1)\n" if ($dbg_values > 1); - $type = 'T'; - - } elsif ($cur =~ /^($Modifier)\s*/) { - print "MODIFIER($1)\n" if ($dbg_values > 1); - $type = 'T'; - - } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { - print "DEFINE($1,$2)\n" if ($dbg_values > 1); - $av_preprocessor = 1; - push(@av_paren_type, $type); - if ($2 ne '') { - $av_pending = 'N'; - } - $type = 'E'; - - } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { - print "UNDEF($1)\n" if ($dbg_values > 1); - $av_preprocessor = 1; - push(@av_paren_type, $type); - - } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { - print "PRE_START($1)\n" if ($dbg_values > 1); - $av_preprocessor = 1; - - push(@av_paren_type, $type); - push(@av_paren_type, $type); - $type = 'E'; - - } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { - print "PRE_RESTART($1)\n" if ($dbg_values > 1); - $av_preprocessor = 1; - - push(@av_paren_type, $av_paren_type[$#av_paren_type]); - - $type = 'E'; - - } elsif ($cur =~ /^(\#\s*(?:endif))/o) { - print "PRE_END($1)\n" if ($dbg_values > 1); - - $av_preprocessor = 1; - - # Assume all arms of the conditional end as this - # one does, and continue as if the #endif was not here. - pop(@av_paren_type); - push(@av_paren_type, $type); - $type = 'E'; - - } elsif ($cur =~ /^(\\\n)/o) { - print "PRECONT($1)\n" if ($dbg_values > 1); - - } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { - print "ATTR($1)\n" if ($dbg_values > 1); - $av_pending = $type; - $type = 'N'; - - } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { - print "SIZEOF($1)\n" if ($dbg_values > 1); - if (defined $2) { - $av_pending = 'V'; - } - $type = 'N'; - - } elsif ($cur =~ /^(if|while|for)\b/o) { - print "COND($1)\n" if ($dbg_values > 1); - $av_pending = 'E'; - $type = 'N'; - - } elsif ($cur =~/^(case)/o) { - print "CASE($1)\n" if ($dbg_values > 1); - $av_pend_colon = 'C'; - $type = 'N'; - - } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { - print "KEYWORD($1)\n" if ($dbg_values > 1); - $type = 'N'; - - } elsif ($cur =~ /^(\()/o) { - print "PAREN('$1')\n" if ($dbg_values > 1); - push(@av_paren_type, $av_pending); - $av_pending = '_'; - $type = 'N'; - - } elsif ($cur =~ /^(\))/o) { - my $new_type = pop(@av_paren_type); - if ($new_type ne '_') { - $type = $new_type; - print "PAREN('$1') -> $type\n" - if ($dbg_values > 1); - } else { - print "PAREN('$1')\n" if ($dbg_values > 1); - } - - } elsif ($cur =~ /^($Ident)\s*\(/o) { - print "FUNC($1)\n" if ($dbg_values > 1); - $type = 'V'; - $av_pending = 'V'; - - } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { - if (defined $2 && $type eq 'C' || $type eq 'T') { - $av_pend_colon = 'B'; - } elsif ($type eq 'E') { - $av_pend_colon = 'L'; - } - print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); - $type = 'V'; - - } elsif ($cur =~ /^($Ident|$Constant)/o) { - print "IDENT($1)\n" if ($dbg_values > 1); - $type = 'V'; - - } elsif ($cur =~ /^($Assignment)/o) { - print "ASSIGN($1)\n" if ($dbg_values > 1); - $type = 'N'; - - } elsif ($cur =~/^(;|{|})/) { - print "END($1)\n" if ($dbg_values > 1); - $type = 'E'; - $av_pend_colon = 'O'; - - } elsif ($cur =~/^(,)/) { - print "COMMA($1)\n" if ($dbg_values > 1); - $type = 'C'; - - } elsif ($cur =~ /^(\?)/o) { - print "QUESTION($1)\n" if ($dbg_values > 1); - $type = 'N'; - - } elsif ($cur =~ /^(:)/o) { - print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); - - substr($var, length($res), 1, $av_pend_colon); - if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { - $type = 'E'; - } else { - $type = 'N'; - } - $av_pend_colon = 'O'; - - } elsif ($cur =~ /^(\[)/o) { - print "CLOSE($1)\n" if ($dbg_values > 1); - $type = 'N'; - - } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { - my $variant; - - print "OPV($1)\n" if ($dbg_values > 1); - if ($type eq 'V') { - $variant = 'B'; - } else { - $variant = 'U'; - } - - substr($var, length($res), 1, $variant); - $type = 'N'; - - } elsif ($cur =~ /^($Operators)/o) { - print "OP($1)\n" if ($dbg_values > 1); - if ($1 ne '++' && $1 ne '--') { - $type = 'N'; - } - - } elsif ($cur =~ /(^.)/o) { - print "C($1)\n" if ($dbg_values > 1); - } - if (defined $1) { - $cur = substr($cur, length($1)); - $res .= $type x length($1); - } - } - - return ($res, $var); -} - -sub possible { - my ($possible, $line) = @_; - my $notPermitted = qr{(?: - ^(?: - $Modifier| - $Storage| - $Type| - DEFINE_\S+ - )$| - ^(?: - goto| - return| - case| - else| - asm|__asm__| - do| - \#| - \#\#| - )(?:\s|$)| - ^(?:typedef|struct|enum)\b - )}x; - warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); - if ($possible !~ $notPermitted) { - # Check for modifiers. - $possible =~ s/\s*$Storage\s*//g; - $possible =~ s/\s*$Sparse\s*//g; - if ($possible =~ /^\s*$/) { - - } elsif ($possible =~ /\s/) { - $possible =~ s/\s*$Type\s*//g; - for my $modifier (split(' ', $possible)) { - if ($modifier !~ $notPermitted) { - warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); - push(@modifierListFile, $modifier); - } - } - - } else { - warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); - push(@typeListFile, $possible); - } - build_types(); - } else { - warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); - } -} - -my $prefix = ''; - -sub show_type { - my ($type) = @_; - - $type =~ tr/[a-z]/[A-Z]/; - - return defined $use_type{$type} if (scalar keys %use_type > 0); - - return !defined $ignore_type{$type}; -} - -sub report { - my ($level, $type, $msg) = @_; - - if (!show_type($type) || - (defined $tst_only && $msg !~ /\Q$tst_only\E/)) { - return 0; - } - my $output = ''; - if ($color) { - if ($level eq 'ERROR') { - $output .= RED; - } elsif ($level eq 'WARNING') { - $output .= YELLOW; - } else { - $output .= GREEN; - } - } - $output .= $prefix . $level . ':'; - if ($show_types) { - $output .= BLUE if ($color); - $output .= "$type:"; - } - $output .= RESET if ($color); - $output .= ' ' . $msg . "\n"; - - if ($showfile) { - my @lines = split("\n", $output, -1); - splice(@lines, 1, 1); - $output = join("\n", @lines); - } - $output = (split('\n', $output))[0] . "\n" if ($terse); - - push(our @report, $output); - - return 1; -} - -sub report_dump { - our @report; -} - -sub fixup_current_range { - my ($lineRef, $offset, $length) = @_; - - if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) { - my $o = $1; - my $l = $2; - my $no = $o + $offset; - my $nl = $l + $length; - $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/; - } -} - -sub fix_inserted_deleted_lines { - my ($linesRef, $insertedRef, $deletedRef) = @_; - - my $range_last_linenr = 0; - my $delta_offset = 0; - - my $old_linenr = 0; - my $new_linenr = 0; - - my $next_insert = 0; - my $next_delete = 0; - - my @lines = (); - - my $inserted = @{$insertedRef}[$next_insert++]; - my $deleted = @{$deletedRef}[$next_delete++]; - - foreach my $old_line (@{$linesRef}) { - my $save_line = 1; - my $line = $old_line; #don't modify the array - if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename - $delta_offset = 0; - } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk - $range_last_linenr = $new_linenr; - fixup_current_range(\$line, $delta_offset, 0); - } - - while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) { - $deleted = @{$deletedRef}[$next_delete++]; - $save_line = 0; - fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1); - } - - while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) { - push(@lines, ${$inserted}{'LINE'}); - $inserted = @{$insertedRef}[$next_insert++]; - $new_linenr++; - fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1); - } - - if ($save_line) { - push(@lines, $line); - $new_linenr++; - } - - $old_linenr++; - } - - return @lines; -} - -sub fix_insert_line { - my ($linenr, $line) = @_; - - my $inserted = { - LINENR => $linenr, - LINE => $line, - }; - push(@fixed_inserted, $inserted); -} - -sub fix_delete_line { - my ($linenr, $line) = @_; - - my $deleted = { - LINENR => $linenr, - LINE => $line, - }; - - push(@fixed_deleted, $deleted); -} - -sub ERROR { - my ($type, $msg) = @_; - - if (report("ERROR", $type, $msg)) { - our $clean = 0; - our $cnt_error++; - return 1; - } - return 0; -} -sub WARN { - my ($type, $msg) = @_; - - if (report("WARNING", $type, $msg)) { - our $clean = 0; - our $cnt_warn++; - return 1; - } - return 0; -} -sub CHK { - my ($type, $msg) = @_; - - if ($check && report("CHECK", $type, $msg)) { - our $clean = 0; - our $cnt_chk++; - return 1; - } - return 0; -} - -sub check_absolute_file { - my ($absolute, $herecurr) = @_; - my $file = $absolute; - - ##print "absolute<$absolute>\n"; - - # See if any suffix of this path is a path within the tree. - while ($file =~ s@^[^/]*/@@) { - if (-f "$root/$file") { - ##print "file<$file>\n"; - last; - } - } - if (! -f _) { - return 0; - } - - # It is, so see if the prefix is acceptable. - my $prefix = $absolute; - substr($prefix, -length($file)) = ''; - - ##print "prefix<$prefix>\n"; - if ($prefix ne ".../") { - WARN("USE_RELATIVE_PATH", - "use relative pathname instead of absolute in changelog text\n" . $herecurr); - } -} - -sub trim { - my ($string) = @_; - - $string =~ s/^\s+|\s+$//g; - - return $string; -} - -sub ltrim { - my ($string) = @_; - - $string =~ s/^\s+//; - - return $string; -} - -sub rtrim { - my ($string) = @_; - - $string =~ s/\s+$//; - - return $string; -} - -sub string_find_replace { - my ($string, $find, $replace) = @_; - - $string =~ s/$find/$replace/g; - - return $string; -} - -sub tabify { - my ($leading) = @_; - - my $source_indent = $tabsize; - my $max_spaces_before_tab = $source_indent - 1; - my $spaces_to_tab = " " x $source_indent; - - #convert leading spaces to tabs - 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; - #Remove spaces before a tab - 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; - - return "$leading"; -} - -sub pos_last_openparen { - my ($line) = @_; - - my $pos = 0; - - my $opens = $line =~ tr/\(/\(/; - my $closes = $line =~ tr/\)/\)/; - - my $last_openparen = 0; - - if (($opens == 0) || ($closes >= $opens)) { - return -1; - } - - my $len = length($line); - - for ($pos = 0; $pos < $len; $pos++) { - my $string = substr($line, $pos); - if ($string =~ /^($FuncArg|$balanced_parens)/) { - $pos += length($1) - 1; - } elsif (substr($line, $pos, 1) eq '(') { - $last_openparen = $pos; - } elsif (index($string, '(') == -1) { - last; - } - } - - return length(expand_tabs(substr($line, 0, $last_openparen))) + 1; -} - -sub get_raw_comment { - my ($line, $rawline) = @_; - my $comment = ''; - - for my $i (0 .. (length($line) - 1)) { - if (substr($line, $i, 1) eq "$;") { - $comment .= substr($rawline, $i, 1); - } - } - - return $comment; -} - -sub process { - my $filename = shift; - - my $linenr=0; - my $prevline=""; - my $prevrawline=""; - my $stashline=""; - my $stashrawline=""; - - my $length; - my $indent; - my $previndent=0; - my $stashindent=0; - - our $clean = 1; - my $signoff = 0; - my $author = ''; - my $authorsignoff = 0; - my $author_sob = ''; - my $is_patch = 0; - my $is_binding_patch = -1; - my $in_header_lines = $file ? 0 : 1; - my $in_commit_log = 0; #Scanning lines before patch - my $has_patch_separator = 0; #Found a --- line - my $has_commit_log = 0; #Encountered lines before patch - my $commit_log_lines = 0; #Number of commit log lines - my $commit_log_possible_stack_dump = 0; - my $commit_log_long_line = 0; - my $commit_log_has_diff = 0; - my $reported_maintainer_file = 0; - my $non_utf8_charset = 0; - - my $last_blank_line = 0; - my $last_coalesced_string_linenr = -1; - - our @report = (); - our $cnt_lines = 0; - our $cnt_error = 0; - our $cnt_warn = 0; - our $cnt_chk = 0; - - # Trace the real file/line as we go. - my $realfile = ''; - my $realline = 0; - my $realcnt = 0; - my $here = ''; - my $context_function; #undef'd unless there's a known function - my $in_comment = 0; - my $comment_edge = 0; - my $first_line = 0; - my $p1_prefix = ''; - - my $prev_values = 'E'; - - # suppression flags - my %suppress_ifbraces; - my %suppress_whiletrailers; - my %suppress_export; - my $suppress_statement = 0; - - my %signatures = (); - - # Pre-scan the patch sanitizing the lines. - # Pre-scan the patch looking for any __setup documentation. - # - my @setup_docs = (); - my $setup_docs = 0; - - my $camelcase_file_seeded = 0; - - my $checklicenseline = 1; - - sanitise_line_reset(); - my $line; - foreach my $rawline (@rawlines) { - $linenr++; - $line = $rawline; - - push(@fixed, $rawline) if ($fix); - - if ($rawline=~/^\+\+\+\s+(\S+)/) { - $setup_docs = 0; - if ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) { - $setup_docs = 1; - } - #next; - } - if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { - $realline=$1-1; - if (defined $2) { - $realcnt=$3+1; - } else { - $realcnt=1+1; - } - $in_comment = 0; - - # Guestimate if this is a continuing comment. Run - # the context looking for a comment "edge". If this - # edge is a close comment then we must be in a comment - # at context start. - my $edge; - my $cnt = $realcnt; - for (my $ln = $linenr + 1; $cnt > 0; $ln++) { - next if (defined $rawlines[$ln - 1] && - $rawlines[$ln - 1] =~ /^-/); - $cnt--; - #print "RAW<$rawlines[$ln - 1]>\n"; - last if (!defined $rawlines[$ln - 1]); - if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && - $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { - ($edge) = $1; - last; - } - } - if (defined $edge && $edge eq '*/') { - $in_comment = 1; - } - - # Guestimate if this is a continuing comment. If this - # is the start of a diff block and this line starts - # ' *' then it is very likely a comment. - if (!defined $edge && - $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) - { - $in_comment = 1; - } - - ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; - sanitise_line_reset($in_comment); - - } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { - # Standardise the strings and chars within the input to - # simplify matching -- only bother with positive lines. - $line = sanitise_line($rawline); - } - push(@lines, $line); - - if ($realcnt > 1) { - $realcnt-- if ($line =~ /^(?:\+| |$)/); - } else { - $realcnt = 0; - } - - #print "==>$rawline\n"; - #print "-->$line\n"; - - if ($setup_docs && $line =~ /^\+/) { - push(@setup_docs, $line); - } - } - - $prefix = ''; - - $realcnt = 0; - $linenr = 0; - $fixlinenr = -1; - foreach my $line (@lines) { - $linenr++; - $fixlinenr++; - my $sline = $line; #copy of $line - $sline =~ s/$;/ /g; #with comments as spaces - - my $rawline = $rawlines[$linenr - 1]; - my $raw_comment = get_raw_comment($line, $rawline); - -# check if it's a mode change, rename or start of a patch - if (!$in_commit_log && - ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || - ($line =~ /^rename (?:from|to) \S+\s*$/ || - $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { - $is_patch = 1; - } - -#extract the line range in the file after the patch is applied - if (!$in_commit_log && - $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { - my $context = $4; - $is_patch = 1; - $first_line = $linenr + 1; - $realline=$1-1; - if (defined $2) { - $realcnt=$3+1; - } else { - $realcnt=1+1; - } - annotate_reset(); - $prev_values = 'E'; - - %suppress_ifbraces = (); - %suppress_whiletrailers = (); - %suppress_export = (); - $suppress_statement = 0; - if ($context =~ /\b(\w+)\s*\(/) { - $context_function = $1; - } else { - undef $context_function; - } - next; - -# track the line number as we move through the hunk, note that -# new versions of GNU diff omit the leading space on completely -# blank context lines so we need to count that too. - } elsif ($line =~ /^( |\+|$)/) { - $realline++; - $realcnt-- if ($realcnt != 0); - - # Measure the line length and indent. - ($length, $indent) = line_stats($rawline); - - # Track the previous line. - ($prevline, $stashline) = ($stashline, $line); - ($previndent, $stashindent) = ($stashindent, $indent); - ($prevrawline, $stashrawline) = ($stashrawline, $rawline); - - #warn "line<$line>\n"; - - } elsif ($realcnt == 1) { - $realcnt--; - } - - my $hunk_line = ($realcnt != 0); - - $here = "#$linenr: " if (!$file); - $here = "#$realline: " if ($file); - - my $found_file = 0; - # extract the filename as it passes - if ($line =~ /^diff --git.*?(\S+)$/) { - $realfile = $1; - $realfile =~ s@^([^/]*)/@@ if (!$file); - $in_commit_log = 0; - $found_file = 1; - } elsif ($line =~ /^\+\+\+\s+(\S+)/) { - $realfile = $1; - $realfile =~ s@^([^/]*)/@@ if (!$file); - $in_commit_log = 0; - - $p1_prefix = $1; - if (!$file && $tree && $p1_prefix ne '' && - -e "$root/$p1_prefix") { - WARN("PATCH_PREFIX", - "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); - } - - if ($realfile =~ m@^include/asm/@) { - ERROR("MODIFIED_INCLUDE_ASM", - "do not modify files in include/asm, change architecture specific files in include/asm-\n" . "$here$rawline\n"); - } - $found_file = 1; - } - -#make up the handle for any error we report on this line - if ($showfile) { - $prefix = "$realfile:$realline: " - } elsif ($emacs) { - if ($file) { - $prefix = "$filename:$realline: "; - } else { - $prefix = "$filename:$linenr: "; - } - } - - if ($found_file) { - if (is_maintained_obsolete($realfile)) { - WARN("OBSOLETE", - "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n"); - } - if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) { - $check = 1; - } else { - $check = $check_orig; - } - $checklicenseline = 1; - - if ($realfile !~ /^MAINTAINERS/) { - my $last_binding_patch = $is_binding_patch; - - $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; - - if (($last_binding_patch != -1) && - ($last_binding_patch ^ $is_binding_patch)) { - WARN("DT_SPLIT_BINDING_PATCH", - "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\n"); - } - } - - next; - } - - $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); - - my $hereline = "$here\n$rawline\n"; - my $herecurr = "$here\n$rawline\n"; - my $hereprev = "$here\n$prevrawline\n$rawline\n"; - - $cnt_lines++ if ($realcnt != 0); - -# Verify the existence of a commit log if appropriate -# 2 is used because a $signature is counted in $commit_log_lines - if ($in_commit_log) { - if ($line !~ /^\s*$/) { - $commit_log_lines++; #could be a $signature - } - } elsif ($has_commit_log && $commit_log_lines < 2) { - WARN("COMMIT_MESSAGE", - "Missing commit description - Add an appropriate one\n"); - $commit_log_lines = 2; #warn only once - } - -# Check if the commit log has what seems like a diff which can confuse patch - if ($in_commit_log && !$commit_log_has_diff && - (($line =~ m@^\s+diff\b.*a/([\w/]+)@ && - $line =~ m@^\s+diff\b.*a/[\w/]+\s+b/$1\b@) || - $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ || - $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) { - ERROR("DIFF_IN_COMMIT_MSG", - "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr); - $commit_log_has_diff = 1; - } - -# Check for incorrect file permissions - if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { - my $permhere = $here . "FILE: $realfile\n"; - if ($realfile !~ m@scripts/@ && - $realfile !~ /\.(py|pl|awk|sh)$/) { - ERROR("EXECUTE_PERMISSIONS", - "do not set execute permissions for source files\n" . $permhere); - } - } - -# Check the patch for a From: - if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { - $author = $1; - my $curline = $linenr; - while(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \t]\s*(.*)/)) { - $author .= $1; - } - $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); - $author =~ s/"//g; - $author = reformat_email($author); - } - -# Check the patch for a signoff: - if ($line =~ /^\s*signed-off-by:\s*(.*)/i) { - $signoff++; - $in_commit_log = 0; - if ($author ne '' && $authorsignoff != 1) { - if (same_email_addresses($1, $author, 1)) { - $authorsignoff = 1; - } else { - my $ctx = $1; - my ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx); - my ($author_name, $author_comment, $author_address, $comment2) = parse_email($author); - - if ($email_address eq $author_address && $email_name eq $author_name) { - $author_sob = $ctx; - $authorsignoff = 2; - } elsif ($email_address eq $author_address) { - $author_sob = $ctx; - $authorsignoff = 3; - } elsif ($email_name eq $author_name) { - $author_sob = $ctx; - $authorsignoff = 4; - - my $address1 = $email_address; - my $address2 = $author_address; - - if ($address1 =~ /(\S+)\+\S+(\@.*)/) { - $address1 = "$1$2"; - } - if ($address2 =~ /(\S+)\+\S+(\@.*)/) { - $address2 = "$1$2"; - } - if ($address1 eq $address2) { - $authorsignoff = 5; - } - } - } - } - } - -# Check if MAINTAINERS and/or NVIDIA-REVIEWERS is being updated. If so, there's probably no need to -# emit the "does MAINTAINERS/NVIDIA-REVIEWERS need updating?" message on file add/move/delete -# Check for patch separator - if ($line =~ /^---$/) { - $has_patch_separator = 1; - $in_commit_log = 0; - } - -# Check if MAINTAINERS is being updated. If so, there's probably no need to -# emit the "does MAINTAINERS need updating?" message on file add/move/delete - if ($line =~ /^\s*MAINTAINERS\s*\|/) { - $reported_maintainer_file = 1; - } - - if ($line =~ /^\s*NVIDIA-REVIEWERS\s*\|/) { - $reported_maintainer_file = 1; - } - -# Check signature styles - if (!$in_header_lines && - $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { - my $space_before = $1; - my $sign_off = $2; - my $space_after = $3; - my $email = $4; - my $ucfirst_sign_off = ucfirst(lc($sign_off)); - - if ($sign_off !~ /$signature_tags/) { - WARN("BAD_SIGN_OFF", - "Non-standard signature: $sign_off\n" . $herecurr); - } - if (defined $space_before && $space_before ne "") { - if (WARN("BAD_SIGN_OFF", - "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] = - "$ucfirst_sign_off $email"; - } - } - if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { - if (WARN("BAD_SIGN_OFF", - "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] = - "$ucfirst_sign_off $email"; - } - - } - if (!defined $space_after || $space_after ne " ") { - if (WARN("BAD_SIGN_OFF", - "Use a single space after $ucfirst_sign_off\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] = - "$ucfirst_sign_off $email"; - } - } - - my ($email_name, $name_comment, $email_address, $comment) = parse_email($email); - my $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment)); - if ($suggested_email eq "") { - ERROR("BAD_SIGN_OFF", - "Unrecognized email address: '$email'\n" . $herecurr); - } else { - my $dequoted = $suggested_email; - $dequoted =~ s/^"//; - $dequoted =~ s/" \]/) || - $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || - $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { - # stack dump address styles - $commit_log_possible_stack_dump = 1; - } - -# Check for line lengths > 75 in commit log, warn once - if ($in_commit_log && !$commit_log_long_line && - length($line) > 75 && - !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ || - # file delta changes - $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ || - # filename then : - $line =~ /^\s*(?:Fixes:|Link:)/i || - # A Fixes: or Link: line - $commit_log_possible_stack_dump)) { - WARN("COMMIT_LOG_LONG_LINE", - "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr); - $commit_log_long_line = 1; - } - -# Reset possible stack dump if a blank line is found - if ($in_commit_log && $commit_log_possible_stack_dump && - $line =~ /^\s*$/) { - $commit_log_possible_stack_dump = 0; - } - -# Check for git id commit length and improperly formed commit descriptions - if ($in_commit_log && !$commit_log_possible_stack_dump && - $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i && - $line !~ /^This reverts commit [0-9a-f]{7,40}/ && - ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i || - ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i && - $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i && - $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) { - my $init_char = "c"; - my $orig_commit = ""; - my $short = 1; - my $long = 0; - my $case = 1; - my $space = 1; - my $hasdesc = 0; - my $hasparens = 0; - my $id = '0123456789ab'; - my $orig_desc = "commit description"; - my $description = ""; - - if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) { - $init_char = $1; - $orig_commit = lc($2); - } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) { - $orig_commit = lc($1); - } - - $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i); - $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i); - $space = 0 if ($line =~ /\bcommit [0-9a-f]/i); - $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/); - if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) { - $orig_desc = $1; - $hasparens = 1; - } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i && - defined $rawlines[$linenr] && - $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) { - $orig_desc = $1; - $hasparens = 1; - } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i && - defined $rawlines[$linenr] && - $rawlines[$linenr] =~ /^\s*[^"]+"\)/) { - $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i; - $orig_desc = $1; - $rawlines[$linenr] =~ /^\s*([^"]+)"\)/; - $orig_desc .= " " . $1; - $hasparens = 1; - } - - ($id, $description) = git_commit_info($orig_commit, - $id, $orig_desc); - - if (defined($id) && - ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) { - ERROR("GIT_COMMIT_ID", - "Please use git commit description style 'commit <12+ chars of sha1> (\"\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr); - } - } - -# Check for added, moved or deleted files - if (!$reported_maintainer_file && !$in_commit_log && - ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ || - $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ || - ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ && - (defined($1) || defined($2))))) { - $is_patch = 1; - $reported_maintainer_file = 1; - WARN("FILE_PATH_CHANGES", - "added, moved or deleted file(s), does MAINTAINERS and/or NVIDIA-REVIEWERS need updating?\n" . $herecurr); - } - -# Check for adding new DT bindings not in schema format - if (!$in_commit_log && - ($line =~ /^new file mode\s*\d+\s*$/) && - ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) { - WARN("DT_SCHEMA_BINDING_PATCH", - "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n"); - } - -# Check for wrappage within a valid hunk of the file - if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { - ERROR("CORRUPTED_PATCH", - "patch seems to be corrupt (line wrapped?)\n" . - $herecurr) if (!$emitted_corrupt++); - } - -# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php - if (($realfile =~ /^$/ || $line =~ /^\+/) && - $rawline !~ m/^$UTF8*$/) { - my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); - - my $blank = copy_spacing($rawline); - my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; - my $hereptr = "$hereline$ptr\n"; - - CHK("INVALID_UTF8", - "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); - } - -# Check if it's the start of a commit log -# (not a header line and we haven't seen the patch filename) - if ($in_header_lines && $realfile =~ /^$/ && - !($rawline =~ /^\s+(?:\S|$)/ || - $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) { - $in_header_lines = 0; - $in_commit_log = 1; - $has_commit_log = 1; - } - -# Check if there is UTF-8 in a commit log when a mail header has explicitly -# declined it, i.e defined some charset where it is missing. - if ($in_header_lines && - $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && - $1 !~ /utf-8/i) { - $non_utf8_charset = 1; - } - - if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && - $rawline =~ /$NON_ASCII_UTF8/) { - WARN("UTF8_BEFORE_PATCH", - "8-bit UTF-8 used in possible commit log\n" . $herecurr); - } - -# Check for absolute kernel paths in commit message - if ($tree && $in_commit_log) { - while ($line =~ m{(?:^|\s)(/\S*)}g) { - my $file = $1; - - if ($file =~ m{^(.*?)(?::\d+)+:?$} && - check_absolute_file($1, $herecurr)) { - # - } else { - check_absolute_file($file, $herecurr); - } - } - } - -# Check for various typo / spelling mistakes - if (defined($misspellings) && - ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) { - while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) { - my $typo = $1; - my $typo_fix = $spelling_fix{lc($typo)}; - $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/); - $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/); - my $msg_level = \&WARN; - $msg_level = \&CHK if ($file); - if (&{$msg_level}("TYPO_SPELLING", - "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/; - } - } - } - -# check for invalid commit id - if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { - my $id; - my $description; - ($id, $description) = git_commit_info($2, undef, undef); - if (!defined($id)) { - WARN("UNKNOWN_COMMIT_ID", - "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); - } - } - -# check for repeated words separated by a single space - if ($rawline =~ /^\+/ || $in_commit_log) { - while ($rawline =~ /\b($word_pattern) (?=($word_pattern))/g) { - - my $first = $1; - my $second = $2; - - if ($first =~ /(?:struct|union|enum)/) { - pos($rawline) += length($first) + length($second) + 1; - next; - } - - next if ($first ne $second); - next if ($first eq 'long'); - - if (WARN("REPEATED_WORD", - "Possible repeated word: '$first'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b$first $second\b/$first/; - } - } - - # if it's a repeated word on consecutive lines in a comment block - if ($prevline =~ /$;+\s*$/ && - $prevrawline =~ /($word_pattern)\s*$/) { - my $last_word = $1; - if ($rawline =~ /^\+\s*\*\s*$last_word /) { - if (WARN("REPEATED_WORD", - "Possible repeated word: '$last_word'\n" . $hereprev) && - $fix) { - $fixed[$fixlinenr] =~ s/(\+\s*\*\s*)$last_word /$1/; - } - } - } - } - -# ignore non-hunk lines and lines being removed - next if (!$hunk_line || $line =~ /^-/); - -#trailing whitespace - if ($line =~ /^\+.*\015/) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - if (ERROR("DOS_LINE_ENDINGS", - "DOS line endings\n" . $herevet) && - $fix) { - $fixed[$fixlinenr] =~ s/[\s\015]+$//; - } - } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - if (ERROR("TRAILING_WHITESPACE", - "trailing whitespace\n" . $herevet) && - $fix) { - $fixed[$fixlinenr] =~ s/\s+$//; - } - - $rpt_cleaners = 1; - } - -# Check for FSF mailing addresses. - if ($rawline =~ /\bwrite to the Free/i || - $rawline =~ /\b675\s+Mass\s+Ave/i || - $rawline =~ /\b59\s+Temple\s+Pl/i || - $rawline =~ /\b51\s+Franklin\s+St/i) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - my $msg_level = \&ERROR; - $msg_level = \&CHK if ($file); - &{$msg_level}("FSF_MAILING_ADDRESS", - "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet) - } - -# check for Kconfig help text having a real description -# Only applies when adding the entry originally, after that we do not have -# sufficient context to determine whether it is indeed long enough. - if ($realfile =~ /Kconfig/ && - # 'choice' is usually the last thing on the line (though - # Kconfig supports named choices), so use a word boundary - # (\b) rather than a whitespace character (\s) - $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) { - my $length = 0; - my $cnt = $realcnt; - my $ln = $linenr + 1; - my $f; - my $is_start = 0; - my $is_end = 0; - for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { - $f = $lines[$ln - 1]; - $cnt-- if ($lines[$ln - 1] !~ /^-/); - $is_end = $lines[$ln - 1] =~ /^\+/; - - next if ($f =~ /^-/); - last if (!$file && $f =~ /^\@\@/); - - if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) { - $is_start = 1; - } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) { - $length = -1; - } - - $f =~ s/^.//; - $f =~ s/#.*//; - $f =~ s/^\s+//; - next if ($f =~ /^$/); - - # This only checks context lines in the patch - # and so hopefully shouldn't trigger false - # positives, even though some of these are - # common words in help texts - if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice| - if|endif|menu|endmenu|source)\b/x) { - $is_end = 1; - last; - } - $length++; - } - if ($is_start && $is_end && $length < $min_conf_desc_length) { - WARN("CONFIG_DESCRIPTION", - "please write a paragraph that describes the config symbol fully\n" . $herecurr); - } - #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; - } - -# check MAINTAINERS entries - if ($realfile =~ /^MAINTAINERS$/) { -# check MAINTAINERS entries for the right form - if ($rawline =~ /^\+[A-Z]:/ && - $rawline !~ /^\+[A-Z]:\t\S/) { - if (WARN("MAINTAINERS_STYLE", - "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; - } - } -# check MAINTAINERS entries for the right ordering too - my $preferred_order = 'MRLSWQBCPTFXNK'; - if ($rawline =~ /^\+[A-Z]:/ && - $prevrawline =~ /^[\+ ][A-Z]:/) { - $rawline =~ /^\+([A-Z]):\s*(.*)/; - my $cur = $1; - my $curval = $2; - $prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/; - my $prev = $1; - my $prevval = $2; - my $curindex = index($preferred_order, $cur); - my $previndex = index($preferred_order, $prev); - if ($curindex < 0) { - WARN("MAINTAINERS_STYLE", - "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr); - } else { - if ($previndex >= 0 && $curindex < $previndex) { - WARN("MAINTAINERS_STYLE", - "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev); - } elsif ((($prev eq 'F' && $cur eq 'F') || - ($prev eq 'X' && $cur eq 'X')) && - ($prevval cmp $curval) > 0) { - WARN("MAINTAINERS_STYLE", - "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev); - } - } - } - } - -# discourage the use of boolean for type definition attributes of Kconfig options - if ($realfile =~ /Kconfig/ && - $line =~ /^\+\s*\bboolean\b/) { - WARN("CONFIG_TYPE_BOOLEAN", - "Use of boolean is deprecated, please use bool instead.\n" . $herecurr); - } - - if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && - ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { - my $flag = $1; - my $replacement = { - 'EXTRA_AFLAGS' => 'asflags-y', - 'EXTRA_CFLAGS' => 'ccflags-y', - 'EXTRA_CPPFLAGS' => 'cppflags-y', - 'EXTRA_LDFLAGS' => 'ldflags-y', - }; - - WARN("DEPRECATED_VARIABLE", - "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); - } - -# check for DT compatible documentation - if (defined $root && - (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) || - ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) { - - my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; - - my $dt_path = $root . "/Documentation/devicetree/bindings/"; - my $vp_file = $dt_path . "vendor-prefixes.yaml"; - - foreach my $compat (@compats) { - my $compat2 = $compat; - $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/; - my $compat3 = $compat; - $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/; - `grep -Erq "$compat|$compat2|$compat3" $dt_path`; - if ( $? >> 8 ) { - WARN("UNDOCUMENTED_DT_STRING", - "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr); - } - - next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; - my $vendor = $1; - `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; - if ( $? >> 8 ) { - WARN("UNDOCUMENTED_DT_STRING", - "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); - } - } - } - -# check for using SPDX license tag at beginning of files - if ($realline == $checklicenseline) { - if ($rawline =~ /^[ \+]\s*\#\!\s*\//) { - $checklicenseline = 2; - } elsif ($rawline =~ /^\+/) { - my $comment = ""; - if ($realfile =~ /\.(h|s|S)$/) { - $comment = '/*'; - } elsif ($realfile =~ /\.(c|dts|dtsi)$/) { - $comment = '//'; - } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) { - $comment = '#'; - } elsif ($realfile =~ /\.rst$/) { - $comment = '..'; - } - -# check SPDX comment style for .[chsS] files - if ($realfile =~ /\.[chsS]$/ && - $rawline =~ /SPDX-License-Identifier:/ && - $rawline !~ m@^\+\s*\Q$comment\E\s*@) { - WARN("SPDX_LICENSE_TAG", - "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); - } - - if ($comment !~ /^$/ && - $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { - WARN("SPDX_LICENSE_TAG", - "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); - } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { - my $spdx_license = $1; - if (!is_SPDX_License_valid($spdx_license)) { - WARN("SPDX_LICENSE_TAG", - "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); - } - if ($realfile =~ m@^Documentation/devicetree/bindings/@ && - not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) { - my $msg_level = \&WARN; - $msg_level = \&CHK if ($file); - if (&{$msg_level}("SPDX_LICENSE_TAG", - - "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/; - } - } - } - } - } - -# check for embedded filenames - if ($rawline =~ /^\+.*\Q$realfile\E/) { - WARN("EMBEDDED_FILENAME", - "It's generally not useful to have the filename in the file\n" . $herecurr); - } - -# check we are in a valid source file if not then ignore this hunk - next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); - -# check for using SPDX-License-Identifier on the wrong line number - if ($realline != $checklicenseline && - $rawline =~ /\bSPDX-License-Identifier:/ && - substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { - WARN("SPDX_LICENSE_TAG", - "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); - } - -# line length limit (with some exclusions) -# -# There are a few types of lines that may extend beyond $max_line_length: -# logging functions like pr_info that end in a string -# lines with a single string -# #defines that are a single string -# lines with an RFC3986 like URL -# -# There are 3 different line length message types: -# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length -# LONG_LINE_STRING a string starts before but extends beyond $max_line_length -# LONG_LINE all other lines longer than $max_line_length -# -# if LONG_LINE is ignored, the other 2 types are also ignored -# - - if ($line =~ /^\+/ && $length > $max_line_length) { - my $msg_type = "LONG_LINE"; - - # Check the allowed long line types first - - # logging functions that end in a string that starts - # before $max_line_length - if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ && - length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { - $msg_type = ""; - - # lines with only strings (w/ possible termination) - # #defines with only strings - } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ || - $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) { - $msg_type = ""; - - # More special cases - } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ || - $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) { - $msg_type = ""; - - # URL ($rawline is used in case the URL is in a comment) - } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) { - $msg_type = ""; - - # Otherwise set the alternate message types - - # a comment starts before $max_line_length - } elsif ($line =~ /($;[\s$;]*)$/ && - length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { - $msg_type = "LONG_LINE_COMMENT" - - # a quoted string starts before $max_line_length - } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ && - length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) { - $msg_type = "LONG_LINE_STRING" - } - - if ($msg_type ne "" && - (show_type("LONG_LINE") || show_type($msg_type))) { - my $msg_level = \&WARN; - $msg_level = \&CHK if ($file); - &{$msg_level}($msg_type, - "line length of $length exceeds $max_line_length columns\n" . $herecurr); - } - } - -# check for adding lines without a newline. - if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { - WARN("MISSING_EOF_NEWLINE", - "adding a line without newline at end of file\n" . $herecurr); - } - -# check we are in a valid source file C or perl if not then ignore this hunk - next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/); - -# at the beginning of a line any tabs must come first and anything -# more than $tabsize must use tabs. - if ($rawline =~ /^\+\s* \t\s*\S/ || - $rawline =~ /^\+\s* \s*/) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - $rpt_cleaners = 1; - if (ERROR("CODE_INDENT", - "code indent should use tabs where possible\n" . $herevet) && - $fix) { - $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; - } - } - -# check for space before tabs. - if ($rawline =~ /^\+/ && $rawline =~ / \t/) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - if (WARN("SPACE_BEFORE_TAB", - "please, no space before tabs\n" . $herevet) && - $fix) { - while ($fixed[$fixlinenr] =~ - s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {} - while ($fixed[$fixlinenr] =~ - s/(^\+.*) +\t/$1\t/) {} - } - } - -# check for assignments on the start of a line - if ($sline =~ /^\+\s+($Assignment)[^=]/) { - CHK("ASSIGNMENT_CONTINUATIONS", - "Assignment operator '$1' should be on the previous line\n" . $hereprev); - } - -# check for && or || at the start of a line - if ($rawline =~ /^\+\s*(&&|\|\|)/) { - CHK("LOGICAL_CONTINUATIONS", - "Logical continuations should be on the previous line\n" . $hereprev); - } - -# check indentation starts on a tab stop - if ($perl_version_ok && - $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { - my $indent = length($1); - if ($indent % $tabsize) { - if (WARN("TABSTOP", - "Statements should start on a tabstop\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e; - } - } - } - -# check multi-line statement indentation matches previous line - if ($perl_version_ok && - $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { - $prevline =~ /^\+(\t*)(.*)$/; - my $oldindent = $1; - my $rest = $2; - - my $pos = pos_last_openparen($rest); - if ($pos >= 0) { - $line =~ /^(\+| )([ \t]*)/; - my $newindent = $2; - - my $goodtabindent = $oldindent . - "\t" x ($pos / $tabsize) . - " " x ($pos % $tabsize); - my $goodspaceindent = $oldindent . " " x $pos; - - if ($newindent ne $goodtabindent && - $newindent ne $goodspaceindent) { - - if (CHK("PARENTHESIS_ALIGNMENT", - "Alignment should match open parenthesis\n" . $hereprev) && - $fix && $line =~ /^\+/) { - $fixed[$fixlinenr] =~ - s/^\+[ \t]*/\+$goodtabindent/; - } - } - } - } - -# check for space after cast like "(int) foo" or "(struct foo) bar" -# avoid checking a few false positives: -# "sizeof(<type>)" or "__alignof__(<type>)" -# function pointer declarations like "(*foo)(int) = bar;" -# structure definitions like "(struct foo) { 0 };" -# multiline macros that define functions -# known attributes or the __attribute__ keyword - if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ && - (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) { - if (CHK("SPACING", - "No space is necessary after a cast\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/(\(\s*$Type\s*\))[ \t]+/$1/; - } - } - -# Block comment styles -# Networking with an initial /* - if ($realfile =~ m@^(drivers/net/|net/)@ && - $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && - $rawline =~ /^\+[ \t]*\*/ && - $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier - WARN("NETWORKING_BLOCK_COMMENT_STYLE", - "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); - } - -# Block comments use * on subsequent lines - if ($prevline =~ /$;[ \t]*$/ && #ends in comment - $prevrawline =~ /^\+.*?\/\*/ && #starting /* - $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ - $rawline =~ /^\+/ && #line is new - $rawline !~ /^\+[ \t]*\*/) { #no leading * - WARN("BLOCK_COMMENT_STYLE", - "Block comments use * on subsequent lines\n" . $hereprev); - } - -# Block comments use */ on trailing lines - if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ - $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ - $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ - $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ - WARN("BLOCK_COMMENT_STYLE", - "Block comments use a trailing */ on a separate line\n" . $herecurr); - } - -# Block comment * alignment - if ($prevline =~ /$;[ \t]*$/ && #ends in comment - $line =~ /^\+[ \t]*$;/ && #leading comment - $rawline =~ /^\+[ \t]*\*/ && #leading * - (($prevrawline =~ /^\+.*?\/\*/ && #leading /* - $prevrawline !~ /\*\/[ \t]*$/) || #no trailing */ - $prevrawline =~ /^\+[ \t]*\*/)) { #leading * - my $oldindent; - $prevrawline =~ m@^\+([ \t]*/?)\*@; - if (defined($1)) { - $oldindent = expand_tabs($1); - } else { - $prevrawline =~ m@^\+(.*/?)\*@; - $oldindent = expand_tabs($1); - } - $rawline =~ m@^\+([ \t]*)\*@; - my $newindent = $1; - $newindent = expand_tabs($newindent); - if (length($oldindent) ne length($newindent)) { - WARN("BLOCK_COMMENT_STYLE", - "Block comments should align the * on each line\n" . $hereprev); - } - } - -# check for missing blank lines after struct/union declarations -# with exceptions for various attributes and macros - if ($prevline =~ /^[\+ ]};?\s*$/ && - $line =~ /^\+/ && - !($line =~ /^\+\s*$/ || - $line =~ /^\+\s*EXPORT_SYMBOL/ || - $line =~ /^\+\s*MODULE_/i || - $line =~ /^\+\s*\#\s*(?:end|elif|else)/ || - $line =~ /^\+[a-z_]*init/ || - $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ || - $line =~ /^\+\s*DECLARE/ || - $line =~ /^\+\s*builtin_[\w_]*driver/ || - $line =~ /^\+\s*__setup/)) { - if (CHK("LINE_SPACING", - "Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) && - $fix) { - fix_insert_line($fixlinenr, "\+"); - } - } - -# check for multiple consecutive blank lines - if ($prevline =~ /^[\+ ]\s*$/ && - $line =~ /^\+\s*$/ && - $last_blank_line != ($linenr - 1)) { - if (CHK("LINE_SPACING", - "Please don't use multiple blank lines\n" . $hereprev) && - $fix) { - fix_delete_line($fixlinenr, $rawline); - } - - $last_blank_line = $linenr; - } - -# check for missing blank lines after declarations - if ($sline =~ /^\+\s+\S/ && #Not at char 1 - # actual declarations - ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || - # function pointer declarations - $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || - # foo bar; where foo is some local typedef or #define - $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || - # known declaration macros - $prevline =~ /^\+\s+$declaration_macros/) && - # for "else if" which can look like "$Ident $Ident" - !($prevline =~ /^\+\s+$c90_Keywords\b/ || - # other possible extensions of declaration lines - $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ || - # not starting a section or a macro "\" extended line - $prevline =~ /(?:\{\s*|\\)$/) && - # looks like a declaration - !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ || - # function pointer declarations - $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ || - # foo bar; where foo is some local typedef or #define - $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ || - # known declaration macros - $sline =~ /^\+\s+$declaration_macros/ || - # start of struct or union or enum - $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || - # start or end of block or continuation of declaration - $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || - # bitfield continuation - $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ || - # other possible extensions of declaration lines - $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) && - # indentation of previous and current line are the same - (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) { - if (WARN("LINE_SPACING", - "Missing a blank line after declarations\n" . $hereprev) && - $fix) { - fix_insert_line($fixlinenr, "\+"); - } - } - -# check for spaces at the beginning of a line. -# Exceptions: -# 1) within comments -# 2) indented preprocessor commands -# 3) hanging labels - if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { - my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - if (WARN("LEADING_SPACE", - "please, no spaces at the start of a line\n" . $herevet) && - $fix) { - $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; - } - } - -# check we are in a valid C source file if not then ignore this hunk - next if ($realfile !~ /\.(h|c)$/); - -# check for unusual line ending [ or ( - if ($line =~ /^\+.*([\[\(])\s*$/) { - CHK("OPEN_ENDED_LINE", - "Lines should not end with a '$1'\n" . $herecurr); - } - -# check if this appears to be the start function declaration, save the name - if ($sline =~ /^\+\{\s*$/ && - $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) { - $context_function = $1; - } - -# check if this appears to be the end of function declaration - if ($sline =~ /^\+\}\s*$/) { - undef $context_function; - } - -# check indentation of any line with a bare else -# (but not if it is a multiple line "if (foo) return bar; else return baz;") -# if the previous line is a break or return and is indented 1 tab more... - if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) { - my $tabs = length($1) + 1; - if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ || - ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ && - defined $lines[$linenr] && - $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) { - WARN("UNNECESSARY_ELSE", - "else is not generally useful after a break or return\n" . $hereprev); - } - } - -# check indentation of a line with a break; -# if the previous line is a goto or return and is indented the same # of tabs - if ($sline =~ /^\+([\t]+)break\s*;\s*$/) { - my $tabs = $1; - if ($prevline =~ /^\+$tabs(?:goto|return)\b/) { - WARN("UNNECESSARY_BREAK", - "break is not useful after a goto or return\n" . $hereprev); - } - } - -# check for RCS/CVS revision markers - if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { - WARN("CVS_KEYWORD", - "CVS style keyword markers, these will _not_ be updated\n". $herecurr); - } - -# check for old HOTPLUG __dev<foo> section markings - if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { - WARN("HOTPLUG_SECTION", - "Using $1 is unnecessary\n" . $herecurr); - } - -# Check for potential 'bare' types - my ($stat, $cond, $line_nr_next, $remain_next, $off_next, - $realline_next); -#print "LINE<$line>\n"; - if ($linenr > $suppress_statement && - $realcnt && $sline =~ /.\s*\S/) { - ($stat, $cond, $line_nr_next, $remain_next, $off_next) = - ctx_statement_block($linenr, $realcnt, 0); - $stat =~ s/\n./\n /g; - $cond =~ s/\n./\n /g; - -#print "linenr<$linenr> <$stat>\n"; - # If this statement has no statement boundaries within - # it there is no point in retrying a statement scan - # until we hit end of it. - my $frag = $stat; $frag =~ s/;+\s*$//; - if ($frag !~ /(?:{|;)/) { -#print "skip<$line_nr_next>\n"; - $suppress_statement = $line_nr_next; - } - - # Find the real next line. - $realline_next = $line_nr_next; - if (defined $realline_next && - (!defined $lines[$realline_next - 1] || - substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { - $realline_next++; - } - - my $s = $stat; - $s =~ s/{.*$//s; - - # Ignore goto labels. - if ($s =~ /$Ident:\*$/s) { - - # Ignore functions being called - } elsif ($s =~ /^.\s*$Ident\s*\(/s) { - - } elsif ($s =~ /^.\s*else\b/s) { - - # declarations always start with types - } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { - my $type = $1; - $type =~ s/\s+/ /g; - possible($type, "A:" . $s); - - # definitions in global scope can only start with types - } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { - possible($1, "B:" . $s); - } - - # any (foo ... *) is a pointer cast, and foo is a type - while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { - possible($1, "C:" . $s); - } - - # Check for any sort of function declaration. - # int foo(something bar, other baz); - # void (*store_gdt)(x86_descr_ptr *); - if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { - my ($name_len) = length($1); - - my $ctx = $s; - substr($ctx, 0, $name_len + 1, ''); - $ctx =~ s/\)[^\)]*$//; - - for my $arg (split(/\s*,\s*/, $ctx)) { - if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { - - possible($1, "D:" . $s); - } - } - } - - } - -# -# Checks which may be anchored in the context. -# - -# Check for switch () and associated case and default -# statements should be at the same indent. - if ($line=~/\bswitch\s*\(.*\)/) { - my $err = ''; - my $sep = ''; - my @ctx = ctx_block_outer($linenr, $realcnt); - shift(@ctx); - for my $ctx (@ctx) { - my ($clen, $cindent) = line_stats($ctx); - if ($ctx =~ /^\+\s*(case\s+|default:)/ && - $indent != $cindent) { - $err .= "$sep$ctx\n"; - $sep = ''; - } else { - $sep = "[...]\n"; - } - } - if ($err ne '') { - ERROR("SWITCH_CASE_INDENT_LEVEL", - "switch and case should be at the same indent\n$hereline$err"); - } - } - -# if/while/etc brace do not go on next line, unless defining a do while loop, -# or if that brace on the next line is for something else - if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { - my $pre_ctx = "$1$2"; - - my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); - - if ($line =~ /^\+\t{6,}/) { - WARN("DEEP_INDENTATION", - "Too many leading tabs - consider code refactoring\n" . $herecurr); - } - - my $ctx_cnt = $realcnt - $#ctx - 1; - my $ctx = join("\n", @ctx); - - my $ctx_ln = $linenr; - my $ctx_skip = $realcnt; - - while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && - defined $lines[$ctx_ln - 1] && - $lines[$ctx_ln - 1] =~ /^-/)) { - ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; - $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); - $ctx_ln++; - } - - #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; - #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; - - if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { - ERROR("OPEN_BRACE", - "that open brace { should be on the previous line\n" . - "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); - } - if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && - $ctx =~ /\)\s*\;\s*$/ && - defined $lines[$ctx_ln - 1]) - { - my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); - if ($nindent > $indent) { - WARN("TRAILING_SEMICOLON", - "trailing semicolon indicates no statements, indent implies otherwise\n" . - "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); - } - } - } - -# Check relative indent for conditionals and blocks. - if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { - ($stat, $cond, $line_nr_next, $remain_next, $off_next) = - ctx_statement_block($linenr, $realcnt, 0) - if (!defined $stat); - my ($s, $c) = ($stat, $cond); - - substr($s, 0, length($c), ''); - - # remove inline comments - $s =~ s/$;/ /g; - $c =~ s/$;/ /g; - - # Find out how long the conditional actually is. - my @newlines = ($c =~ /\n/gs); - my $cond_lines = 1 + $#newlines; - - # Make sure we remove the line prefixes as we have - # none on the first line, and are going to readd them - # where necessary. - $s =~ s/\n./\n/gs; - while ($s =~ /\n\s+\\\n/) { - $cond_lines += $s =~ s/\n\s+\\\n/\n/g; - } - - # We want to check the first line inside the block - # starting at the end of the conditional, so remove: - # 1) any blank line termination - # 2) any opening brace { on end of the line - # 3) any do (...) { - my $continuation = 0; - my $check = 0; - $s =~ s/^.*\bdo\b//; - $s =~ s/^\s*{//; - if ($s =~ s/^\s*\\//) { - $continuation = 1; - } - if ($s =~ s/^\s*?\n//) { - $check = 1; - $cond_lines++; - } - - # Also ignore a loop construct at the end of a - # preprocessor statement. - if (($prevline =~ /^.\s*#\s*define\s/ || - $prevline =~ /\\\s*$/) && $continuation == 0) { - $check = 0; - } - - my $cond_ptr = -1; - $continuation = 0; - while ($cond_ptr != $cond_lines) { - $cond_ptr = $cond_lines; - - # If we see an #else/#elif then the code - # is not linear. - if ($s =~ /^\s*\#\s*(?:else|elif)/) { - $check = 0; - } - - # Ignore: - # 1) blank lines, they should be at 0, - # 2) preprocessor lines, and - # 3) labels. - if ($continuation || - $s =~ /^\s*?\n/ || - $s =~ /^\s*#\s*?/ || - $s =~ /^\s*$Ident\s*:/) { - $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; - if ($s =~ s/^.*?\n//) { - $cond_lines++; - } - } - } - - my (undef, $sindent) = line_stats("+" . $s); - my $stat_real = raw_line($linenr, $cond_lines); - - # Check if either of these lines are modified, else - # this is not this patch's fault. - if (!defined($stat_real) || - $stat !~ /^\+/ && $stat_real !~ /^\+/) { - $check = 0; - } - if (defined($stat_real) && $cond_lines > 1) { - $stat_real = "[...]\n$stat_real"; - } - - #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; - - if ($check && $s ne '' && - (($sindent % $tabsize) != 0 || - ($sindent < $indent) || - ($sindent == $indent && - ($s !~ /^\s*(?:\}|\{|else\b)/)) || - ($sindent > $indent + $tabsize))) { - WARN("SUSPECT_CODE_INDENT", - "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); - } - } - - # Track the 'values' across context and added lines. - my $opline = $line; $opline =~ s/^./ /; - my ($curr_values, $curr_vars) = - annotate_values($opline . "\n", $prev_values); - $curr_values = $prev_values . $curr_values; - if ($dbg_values) { - my $outline = $opline; $outline =~ s/\t/ /g; - print "$linenr > .$outline\n"; - print "$linenr > $curr_values\n"; - print "$linenr > $curr_vars\n"; - } - $prev_values = substr($curr_values, -1); - -#ignore lines not being added - next if ($line =~ /^[^\+]/); - -# check for self assignments used to avoid compiler warnings -# e.g.: int foo = foo, *bar = NULL; -# struct foo bar = *(&(bar)); - if ($line =~ /^\+\s*(?:$Declare)?([A-Za-z_][A-Za-z\d_]*)\s*=/) { - my $var = $1; - if ($line =~ /^\+\s*(?:$Declare)?$var\s*=\s*(?:$var|\*\s*\(?\s*&\s*\(?\s*$var\s*\)?\s*\)?)\s*[;,]/) { - WARN("SELF_ASSIGNMENT", - "Do not use self-assignments to avoid compiler warnings\n" . $herecurr); - } - } - -# check for dereferences that span multiple lines - if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ && - $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) { - $prevline =~ /($Lval\s*(?:\.|->))\s*$/; - my $ref = $1; - $line =~ /^.\s*($Lval)/; - $ref .= $1; - $ref =~ s/\s//g; - WARN("MULTILINE_DEREFERENCE", - "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev); - } - -# check for declarations of signed or unsigned without int - while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) { - my $type = $1; - my $var = $2; - $var = "" if (!defined $var); - if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) { - my $sign = $1; - my $pointer = $2; - - $pointer = "" if (!defined $pointer); - - if (WARN("UNSPECIFIED_INT", - "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) && - $fix) { - my $decl = trim($sign) . " int "; - my $comp_pointer = $pointer; - $comp_pointer =~ s/\s//g; - $decl .= $comp_pointer; - $decl = rtrim($decl) if ($var eq ""); - $fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@; - } - } - } - -# TEST: allow direct testing of the type matcher. - if ($dbg_type) { - if ($line =~ /^.\s*$Declare\s*$/) { - ERROR("TEST_TYPE", - "TEST: is type\n" . $herecurr); - } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { - ERROR("TEST_NOT_TYPE", - "TEST: is not type ($1 is)\n". $herecurr); - } - next; - } -# TEST: allow direct testing of the attribute matcher. - if ($dbg_attr) { - if ($line =~ /^.\s*$Modifier\s*$/) { - ERROR("TEST_ATTR", - "TEST: is attr\n" . $herecurr); - } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { - ERROR("TEST_NOT_ATTR", - "TEST: is not attr ($1 is)\n". $herecurr); - } - next; - } - -# check for initialisation to aggregates open brace on the next line - if ($line =~ /^.\s*{/ && - $prevline =~ /(?:^|[^=])=\s*$/) { - if (ERROR("OPEN_BRACE", - "that open brace { should be on the previous line\n" . $hereprev) && - $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { - fix_delete_line($fixlinenr - 1, $prevrawline); - fix_delete_line($fixlinenr, $rawline); - my $fixedline = $prevrawline; - $fixedline =~ s/\s*=\s*$/ = {/; - fix_insert_line($fixlinenr, $fixedline); - $fixedline = $line; - $fixedline =~ s/^(.\s*)\{\s*/$1/; - fix_insert_line($fixlinenr, $fixedline); - } - } - -# -# Checks which are anchored on the added line. -# - -# check for malformed paths in #include statements (uses RAW line) - if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { - my $path = $1; - if ($path =~ m{//}) { - ERROR("MALFORMED_INCLUDE", - "malformed #include filename\n" . $herecurr); - } - if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { - ERROR("UAPI_INCLUDE", - "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); - } - } - -# no C99 // comments - if ($line =~ m{//}) { - if (ERROR("C99_COMMENTS", - "do not use C99 // comments\n" . $herecurr) && - $fix) { - my $line = $fixed[$fixlinenr]; - if ($line =~ /\/\/(.*)$/) { - my $comment = trim($1); - $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@; - } - } - } - # Remove C99 comments. - $line =~ s@//.*@@; - $opline =~ s@//.*@@; - -# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider -# the whole statement. -#print "APW <$lines[$realline_next - 1]>\n"; - if (defined $realline_next && - exists $lines[$realline_next - 1] && - !defined $suppress_export{$realline_next} && - ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || - $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { - # Handle definitions which produce identifiers with - # a prefix: - # XXX(foo); - # EXPORT_SYMBOL(something_foo); - my $name = $1; - if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && - $name =~ /^${Ident}_$2/) { -#print "FOO C name<$name>\n"; - $suppress_export{$realline_next} = 1; - - } elsif ($stat !~ /(?: - \n.}\s*$| - ^.DEFINE_$Ident\(\Q$name\E\)| - ^.DECLARE_$Ident\(\Q$name\E\)| - ^.LIST_HEAD\(\Q$name\E\)| - ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| - \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() - )/x) { -#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; - $suppress_export{$realline_next} = 2; - } else { - $suppress_export{$realline_next} = 1; - } - } - if (!defined $suppress_export{$linenr} && - $prevline =~ /^.\s*$/ && - ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || - $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { -#print "FOO B <$lines[$linenr - 1]>\n"; - $suppress_export{$linenr} = 2; - } - if (defined $suppress_export{$linenr} && - $suppress_export{$linenr} == 2) { - WARN("EXPORT_SYMBOL", - "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); - } - -# check for global initialisers. - if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) { - if (ERROR("GLOBAL_INITIALISERS", - "do not initialise globals to $1\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/; - } - } -# check for static initialisers. - if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) { - if (ERROR("INITIALISED_STATIC", - "do not initialise statics to $1\n" . - $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/; - } - } - -# check for misordered declarations of char/short/int/long with signed/unsigned - while ($sline =~ m{(\b$TypeMisordered\b)}g) { - my $tmp = trim($1); - WARN("MISORDERED_TYPE", - "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); - } - -# check for unnecessary <signed> int declarations of short/long/long long - while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { - my $type = trim($1); - next if ($type !~ /\bint\b/); - next if ($type !~ /\b(?:short|long\s+long|long)\b/); - my $new_type = $type; - $new_type =~ s/\b\s*int\s*\b/ /; - $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; - $new_type =~ s/^const\s+//; - $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); - $new_type = "const $new_type" if ($type =~ /^const\b/); - $new_type =~ s/\s+/ /g; - $new_type = trim($new_type); - if (WARN("UNNECESSARY_INT", - "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; - } - } - -# check for static const char * arrays. - if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { - WARN("STATIC_CONST_CHAR_ARRAY", - "static const char * array should probably be static const char * const\n" . - $herecurr); - } - -# check for initialized const char arrays that should be static const - if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { - if (WARN("STATIC_CONST_CHAR_ARRAY", - "const array should probably be static const\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; - } - } - -# check for static char foo[] = "bar" declarations. - if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { - WARN("STATIC_CONST_CHAR_ARRAY", - "static char array declaration should probably be static const char\n" . - $herecurr); - } - -# check for const <foo> const where <foo> is not a pointer or array type - if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { - my $found = $1; - if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) { - WARN("CONST_CONST", - "'const $found const *' should probably be 'const $found * const'\n" . $herecurr); - } elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) { - WARN("CONST_CONST", - "'const $found const' should probably be 'const $found'\n" . $herecurr); - } - } - -# check for non-global char *foo[] = {"bar", ...} declarations. - if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) { - WARN("STATIC_CONST_CHAR_ARRAY", - "char * array declaration might be better as static const\n" . - $herecurr); - } - -# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo) - if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) { - my $array = $1; - if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) { - my $array_div = $1; - if (WARN("ARRAY_SIZE", - "Prefer ARRAY_SIZE($array)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/; - } - } - } - -# check for function declarations without arguments like "int foo()" - if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) { - if (ERROR("FUNCTION_WITHOUT_ARGS", - "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/; - } - } - -# check for new typedefs, only function parameters and sparse annotations -# make sense. - if ($line =~ /\btypedef\s/ && - $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && - $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && - $line !~ /\b$typeTypedefs\b/ && - $line !~ /\b__bitwise\b/) { - WARN("NEW_TYPEDEFS", - "do not add new typedefs\n" . $herecurr); - } - -# * goes on variable not on type - # (char*[ const]) - while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { - #print "AA<$1>\n"; - my ($ident, $from, $to) = ($1, $2, $2); - - # Should start with a space. - $to =~ s/^(\S)/ $1/; - # Should not end with a space. - $to =~ s/\s+$//; - # '*'s should not have spaces between. - while ($to =~ s/\*\s+\*/\*\*/) { - } - -## print "1: from<$from> to<$to> ident<$ident>\n"; - if ($from ne $to) { - if (ERROR("POINTER_LOCATION", - "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && - $fix) { - my $sub_from = $ident; - my $sub_to = $ident; - $sub_to =~ s/\Q$from\E/$to/; - $fixed[$fixlinenr] =~ - s@\Q$sub_from\E@$sub_to@; - } - } - } - while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { - #print "BB<$1>\n"; - my ($match, $from, $to, $ident) = ($1, $2, $2, $3); - - # Should start with a space. - $to =~ s/^(\S)/ $1/; - # Should not end with a space. - $to =~ s/\s+$//; - # '*'s should not have spaces between. - while ($to =~ s/\*\s+\*/\*\*/) { - } - # Modifiers should have spaces. - $to =~ s/(\b$Modifier$)/$1 /; - -## print "2: from<$from> to<$to> ident<$ident>\n"; - if ($from ne $to && $ident !~ /^$Modifier$/) { - if (ERROR("POINTER_LOCATION", - "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && - $fix) { - - my $sub_from = $match; - my $sub_to = $match; - $sub_to =~ s/\Q$from\E/$to/; - $fixed[$fixlinenr] =~ - s@\Q$sub_from\E@$sub_to@; - } - } - } - -# avoid BUG() or BUG_ON() - if ($line =~ /\b(?:BUG|BUG_ON)\b/) { - my $msg_level = \&WARN; - $msg_level = \&CHK if ($file); - &{$msg_level}("AVOID_BUG", - "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr); - } - -# avoid LINUX_VERSION_CODE - if ($line =~ /\bLINUX_VERSION_CODE\b/) { - WARN("LINUX_VERSION_CODE", - "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); - } - -# check for uses of printk_ratelimit - if ($line =~ /\bprintk_ratelimit\s*\(/) { - WARN("PRINTK_RATELIMITED", - "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); - } - -# printk should use KERN_* levels - if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) { - WARN("PRINTK_WITHOUT_KERN_LEVEL", - "printk() should include KERN_<LEVEL> facility level\n" . $herecurr); - } - - if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { - my $orig = $1; - my $level = lc($orig); - $level = "warn" if ($level eq "warning"); - my $level2 = $level; - $level2 = "dbg" if ($level eq "debug"); - WARN("PREFER_PR_LEVEL", - "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); - } - - if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { - my $orig = $1; - my $level = lc($orig); - $level = "warn" if ($level eq "warning"); - $level = "dbg" if ($level eq "debug"); - WARN("PREFER_DEV_LEVEL", - "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); - } - -# trace_printk should not be used in production code. - if ($line =~ /\b(trace_printk|trace_puts|ftrace_vprintk)\s*\(/) { - WARN("TRACE_PRINTK", - "Do not use $1() in production code (this can be ignored if built only with a debug config option)\n" . $herecurr); - } - -# ENOSYS means "bad syscall nr" and nothing else. This will have a small -# number of false positives, but assembly files are not checked, so at -# least the arch entry code will not trigger this warning. - if ($line =~ /\bENOSYS\b/) { - WARN("ENOSYS", - "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr); - } - -# ENOTSUPP is not a standard error code and should be avoided in new patches. -# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP. -# Similarly to ENOSYS warning a small number of false positives is expected. - if (!$file && $line =~ /\bENOTSUPP\b/) { - if (WARN("ENOTSUPP", - "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/; - } - } - -# function brace can't be on same line, except for #defines of do while, -# or if closed on same line - if ($perl_version_ok && - $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && - $sline !~ /\#\s*define\b.*do\s*\{/ && - $sline !~ /}/) { - if (ERROR("OPEN_BRACE", - "open brace '{' following function definitions go on the next line\n" . $herecurr) && - $fix) { - fix_delete_line($fixlinenr, $rawline); - my $fixed_line = $rawline; - $fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*)\{(.*)$/; - my $line1 = $1; - my $line2 = $2; - fix_insert_line($fixlinenr, ltrim($line1)); - fix_insert_line($fixlinenr, "\+{"); - if ($line2 !~ /^\s*$/) { - fix_insert_line($fixlinenr, "\+\t" . trim($line2)); - } - } - } - -# open braces for enum, union and struct go on the same line. - if ($line =~ /^.\s*{/ && - $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { - if (ERROR("OPEN_BRACE", - "open brace '{' following $1 go on the same line\n" . $hereprev) && - $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { - fix_delete_line($fixlinenr - 1, $prevrawline); - fix_delete_line($fixlinenr, $rawline); - my $fixedline = rtrim($prevrawline) . " {"; - fix_insert_line($fixlinenr, $fixedline); - $fixedline = $rawline; - $fixedline =~ s/^(.\s*)\{\s*/$1\t/; - if ($fixedline !~ /^\+\s*$/) { - fix_insert_line($fixlinenr, $fixedline); - } - } - } - -# missing space after union, struct or enum definition - if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { - if (WARN("SPACING", - "missing space after $1 definition\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; - } - } - -# Function pointer declarations -# check spacing between type, funcptr, and args -# canonical declaration is "type (*funcptr)(args...)" - if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) { - my $declare = $1; - my $pre_pointer_space = $2; - my $post_pointer_space = $3; - my $funcname = $4; - my $post_funcname_space = $5; - my $pre_args_space = $6; - -# the $Declare variable will capture all spaces after the type -# so check it for a missing trailing missing space but pointer return types -# don't need a space so don't warn for those. - my $post_declare_space = ""; - if ($declare =~ /(\s+)$/) { - $post_declare_space = $1; - $declare = rtrim($declare); - } - if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) { - WARN("SPACING", - "missing space after return type\n" . $herecurr); - $post_declare_space = " "; - } - -# unnecessary space "type (*funcptr)(args...)" -# This test is not currently implemented because these declarations are -# equivalent to -# int foo(int bar, ...) -# and this is form shouldn't/doesn't generate a checkpatch warning. -# -# elsif ($declare =~ /\s{2,}$/) { -# WARN("SPACING", -# "Multiple spaces after return type\n" . $herecurr); -# } - -# unnecessary space "type ( *funcptr)(args...)" - if (defined $pre_pointer_space && - $pre_pointer_space =~ /^\s/) { - WARN("SPACING", - "Unnecessary space after function pointer open parenthesis\n" . $herecurr); - } - -# unnecessary space "type (* funcptr)(args...)" - if (defined $post_pointer_space && - $post_pointer_space =~ /^\s/) { - WARN("SPACING", - "Unnecessary space before function pointer name\n" . $herecurr); - } - -# unnecessary space "type (*funcptr )(args...)" - if (defined $post_funcname_space && - $post_funcname_space =~ /^\s/) { - WARN("SPACING", - "Unnecessary space after function pointer name\n" . $herecurr); - } - -# unnecessary space "type (*funcptr) (args...)" - if (defined $pre_args_space && - $pre_args_space =~ /^\s/) { - WARN("SPACING", - "Unnecessary space before function pointer arguments\n" . $herecurr); - } - - if (show_type("SPACING") && $fix) { - $fixed[$fixlinenr] =~ - s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex; - } - } - -# check for spacing round square brackets; allowed: -# 1. with a type on the left -- int [] a; -# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, -# 3. inside a curly brace -- = { [0...10] = 5 } - while ($line =~ /(.*?\s)\[/g) { - my ($where, $prefix) = ($-[1], $1); - if ($prefix !~ /$Type\s+$/ && - ($where != 0 || $prefix !~ /^.\s+$/) && - $prefix !~ /[{,:]\s+$/) { - if (ERROR("BRACKET_SPACE", - "space prohibited before open square bracket '['\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/^(\+.*?)\s+\[/$1\[/; - } - } - } - -# check for spaces between functions and their parentheses. - while ($line =~ /($Ident)\s+\(/g) { - my $name = $1; - my $ctx_before = substr($line, 0, $-[1]); - my $ctx = "$ctx_before$name"; - - # Ignore those directives where spaces _are_ permitted. - if ($name =~ /^(?: - if|for|while|switch|return|case| - volatile|__volatile__| - __attribute__|format|__extension__| - asm|__asm__)$/x) - { - # cpp #define statements have non-optional spaces, ie - # if there is a space between the name and the open - # parenthesis it is simply not a parameter group. - } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { - - # cpp #elif statement condition may start with a ( - } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { - - # If this whole things ends with a type its most - # likely a typedef for a function. - } elsif ($ctx =~ /$Type$/) { - - } else { - if (WARN("SPACING", - "space prohibited between function name and open parenthesis '('\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\b$name\s+\(/$name\(/; - } - } - } - -# Check operator spacing. - if (!($line=~/\#\s*include/)) { - my $fixed_line = ""; - my $line_fixed = 0; - - my $ops = qr{ - <<=|>>=|<=|>=|==|!=| - \+=|-=|\*=|\/=|%=|\^=|\|=|&=| - =>|->|<<|>>|<|>|=|!|~| - &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| - \?:|\?|: - }x; - my @elements = split(/($ops|;)/, $opline); - -## print("element count: <" . $#elements . ">\n"); -## foreach my $el (@elements) { -## print("el: <$el>\n"); -## } - - my @fix_elements = (); - my $off = 0; - - foreach my $el (@elements) { - push(@fix_elements, substr($rawline, $off, length($el))); - $off += length($el); - } - - $off = 0; - - my $blank = copy_spacing($opline); - my $last_after = -1; - - for (my $n = 0; $n < $#elements; $n += 2) { - - my $good = $fix_elements[$n] . $fix_elements[$n + 1]; - -## print("n: <$n> good: <$good>\n"); - - $off += length($elements[$n]); - - # Pick up the preceding and succeeding characters. - my $ca = substr($opline, 0, $off); - my $cc = ''; - if (length($opline) >= ($off + length($elements[$n + 1]))) { - $cc = substr($opline, $off + length($elements[$n + 1])); - } - my $cb = "$ca$;$cc"; - - my $a = ''; - $a = 'V' if ($elements[$n] ne ''); - $a = 'W' if ($elements[$n] =~ /\s$/); - $a = 'C' if ($elements[$n] =~ /$;$/); - $a = 'B' if ($elements[$n] =~ /(\[|\()$/); - $a = 'O' if ($elements[$n] eq ''); - $a = 'E' if ($ca =~ /^\s*$/); - - my $op = $elements[$n + 1]; - - my $c = ''; - if (defined $elements[$n + 2]) { - $c = 'V' if ($elements[$n + 2] ne ''); - $c = 'W' if ($elements[$n + 2] =~ /^\s/); - $c = 'C' if ($elements[$n + 2] =~ /^$;/); - $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); - $c = 'O' if ($elements[$n + 2] eq ''); - $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); - } else { - $c = 'E'; - } - - my $ctx = "${a}x${c}"; - - my $at = "(ctx:$ctx)"; - - my $ptr = substr($blank, 0, $off) . "^"; - my $hereptr = "$hereline$ptr\n"; - - # Pull out the value of this operator. - my $op_type = substr($curr_values, $off + 1, 1); - - # Get the full operator variant. - my $opv = $op . substr($curr_vars, $off, 1); - - # Ignore operators passed as parameters. - if ($op_type ne 'V' && - $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) { - -# # Ignore comments -# } elsif ($op =~ /^$;+$/) { - - # ; should have either the end of line or a space or \ after it - } elsif ($op eq ';') { - if ($ctx !~ /.x[WEBC]/ && - $cc !~ /^\\/ && $cc !~ /^;/) { - if (ERROR("SPACING", - "space required after that '$op' $at\n" . $hereptr)) { - $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; - $line_fixed = 1; - } - } - - # // is a comment - } elsif ($op eq '//') { - - # : when part of a bitfield - } elsif ($opv eq ':B') { - # skip the bitfield test for now - - # No spaces for: - # -> - } elsif ($op eq '->') { - if ($ctx =~ /Wx.|.xW/) { - if (ERROR("SPACING", - "spaces prohibited around that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); - if (defined $fix_elements[$n + 2]) { - $fix_elements[$n + 2] =~ s/^\s+//; - } - $line_fixed = 1; - } - } - - # , must not have a space before and must have a space on the right. - } elsif ($op eq ',') { - my $rtrim_before = 0; - my $space_after = 0; - if ($ctx =~ /Wx./) { - if (ERROR("SPACING", - "space prohibited before that '$op' $at\n" . $hereptr)) { - $line_fixed = 1; - $rtrim_before = 1; - } - } - if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { - if (ERROR("SPACING", - "space required after that '$op' $at\n" . $hereptr)) { - $line_fixed = 1; - $last_after = $n; - $space_after = 1; - } - } - if ($rtrim_before || $space_after) { - if ($rtrim_before) { - $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); - } else { - $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); - } - if ($space_after) { - $good .= " "; - } - } - - # '*' as part of a type definition -- reported already. - } elsif ($opv eq '*_') { - #warn "'*' is part of type\n"; - - # unary operators should have a space before and - # none after. May be left adjacent to another - # unary operator, or a cast - } elsif ($op eq '!' || $op eq '~' || - $opv eq '*U' || $opv eq '-U' || - $opv eq '&U' || $opv eq '&&U') { - if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { - if (ERROR("SPACING", - "space required before that '$op' $at\n" . $hereptr)) { - if ($n != $last_after + 2) { - $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]); - $line_fixed = 1; - } - } - } - if ($op eq '*' && $cc =~/\s*$Modifier\b/) { - # A unary '*' may be const - - } elsif ($ctx =~ /.xW/) { - if (ERROR("SPACING", - "space prohibited after that '$op' $at\n" . $hereptr)) { - $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]); - if (defined $fix_elements[$n + 2]) { - $fix_elements[$n + 2] =~ s/^\s+//; - } - $line_fixed = 1; - } - } - - # unary ++ and unary -- are allowed no space on one side. - } elsif ($op eq '++' or $op eq '--') { - if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { - if (ERROR("SPACING", - "space required one side of that '$op' $at\n" . $hereptr)) { - $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " "; - $line_fixed = 1; - } - } - if ($ctx =~ /Wx[BE]/ || - ($ctx =~ /Wx./ && $cc =~ /^;/)) { - if (ERROR("SPACING", - "space prohibited before that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); - $line_fixed = 1; - } - } - if ($ctx =~ /ExW/) { - if (ERROR("SPACING", - "space prohibited after that '$op' $at\n" . $hereptr)) { - $good = $fix_elements[$n] . trim($fix_elements[$n + 1]); - if (defined $fix_elements[$n + 2]) { - $fix_elements[$n + 2] =~ s/^\s+//; - } - $line_fixed = 1; - } - } - - # << and >> may either have or not have spaces both sides - } elsif ($op eq '<<' or $op eq '>>' or - $op eq '&' or $op eq '^' or $op eq '|' or - $op eq '+' or $op eq '-' or - $op eq '*' or $op eq '/' or - $op eq '%') - { - if ($check) { - if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) { - if (CHK("SPACING", - "spaces preferred around that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; - $fix_elements[$n + 2] =~ s/^\s+//; - $line_fixed = 1; - } - } elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) { - if (CHK("SPACING", - "space preferred before that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); - $line_fixed = 1; - } - } - } elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { - if (ERROR("SPACING", - "need consistent spacing around '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; - if (defined $fix_elements[$n + 2]) { - $fix_elements[$n + 2] =~ s/^\s+//; - } - $line_fixed = 1; - } - } - - # A colon needs no spaces before when it is - # terminating a case value or a label. - } elsif ($opv eq ':C' || $opv eq ':L') { - if ($ctx =~ /Wx./) { - if (ERROR("SPACING", - "space prohibited before that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]); - $line_fixed = 1; - } - } - - # All the others need spaces both sides. - } elsif ($ctx !~ /[EWC]x[CWE]/) { - my $ok = 0; - - # Ignore email addresses <foo@bar> - if (($op eq '<' && - $cc =~ /^\S+\@\S+>/) || - ($op eq '>' && - $ca =~ /<\S+\@\S+$/)) - { - $ok = 1; - } - - # for asm volatile statements - # ignore a colon with another - # colon immediately before or after - if (($op eq ':') && - ($ca =~ /:$/ || $cc =~ /^:/)) { - $ok = 1; - } - - # messages are ERROR, but ?: are CHK - if ($ok == 0) { - my $msg_level = \&ERROR; - $msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/); - - if (&{$msg_level}("SPACING", - "spaces required around that '$op' $at\n" . $hereptr)) { - $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; - if (defined $fix_elements[$n + 2]) { - $fix_elements[$n + 2] =~ s/^\s+//; - } - $line_fixed = 1; - } - } - } - $off += length($elements[$n + 1]); - -## print("n: <$n> GOOD: <$good>\n"); - - $fixed_line = $fixed_line . $good; - } - - if (($#elements % 2) == 0) { - $fixed_line = $fixed_line . $fix_elements[$#elements]; - } - - if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) { - $fixed[$fixlinenr] = $fixed_line; - } - - - } - -# check for whitespace before a non-naked semicolon - if ($line =~ /^\+.*\S\s+;\s*$/) { - if (WARN("SPACING", - "space prohibited before semicolon\n" . $herecurr) && - $fix) { - 1 while $fixed[$fixlinenr] =~ - s/^(\+.*\S)\s+;/$1;/; - } - } - -# check for multiple assignments - if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { - CHK("MULTIPLE_ASSIGNMENTS", - "multiple assignments should be avoided\n" . $herecurr); - } - -## # check for multiple declarations, allowing for a function declaration -## # continuation. -## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && -## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { -## -## # Remove any bracketed sections to ensure we do not -## # falsly report the parameters of functions. -## my $ln = $line; -## while ($ln =~ s/\([^\(\)]*\)//g) { -## } -## if ($ln =~ /,/) { -## WARN("MULTIPLE_DECLARATION", -## "declaring multiple variables together should be avoided\n" . $herecurr); -## } -## } - -#need space before brace following if, while, etc - if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || - $line =~ /\b(?:else|do)\{/) { - if (ERROR("SPACING", - "space required before the open brace '{'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; - } - } - -## # check for blank lines before declarations -## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && -## $prevrawline =~ /^.\s*$/) { -## WARN("SPACING", -## "No blank lines before declarations\n" . $hereprev); -## } -## - -# closing brace should have a space following it when it has anything -# on the line - if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { - if (ERROR("SPACING", - "space required after that close brace '}'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/}((?!(?:,|;|\)))\S)/} $1/; - } - } - -# check spacing on square brackets - if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { - if (ERROR("SPACING", - "space prohibited after that open square bracket '['\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\[\s+/\[/; - } - } - if ($line =~ /\s\]/) { - if (ERROR("SPACING", - "space prohibited before that close square bracket ']'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\s+\]/\]/; - } - } - -# check spacing on parentheses - if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && - $line !~ /for\s*\(\s+;/) { - if (ERROR("SPACING", - "space prohibited after that open parenthesis '('\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\(\s+/\(/; - } - } - if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && - $line !~ /for\s*\(.*;\s+\)/ && - $line !~ /:\s+\)/) { - if (ERROR("SPACING", - "space prohibited before that close parenthesis ')'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\s+\)/\)/; - } - } - -# check unnecessary parentheses around addressof/dereference single $Lvals -# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar - - while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) { - my $var = $1; - if (CHK("UNNECESSARY_PARENTHESES", - "Unnecessary parentheses around $var\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/; - } - } - -# check for unnecessary parentheses around function pointer uses -# ie: (foo->bar)(); should be foo->bar(); -# but not "if (foo->bar) (" to avoid some false positives - if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) { - my $var = $2; - if (CHK("UNNECESSARY_PARENTHESES", - "Unnecessary parentheses around function pointer $var\n" . $herecurr) && - $fix) { - my $var2 = deparenthesize($var); - $var2 =~ s/\s//g; - $fixed[$fixlinenr] =~ s/\Q$var\E/$var2/; - } - } - -# check for unnecessary parentheses around comparisons in if uses -# when !drivers/staging or command-line uses --strict - if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && - $perl_version_ok && defined($stat) && - $stat =~ /(^.\s*if\s*($balanced_parens))/) { - my $if_stat = $1; - my $test = substr($2, 1, -1); - my $herectx; - while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) { - my $match = $1; - # avoid parentheses around potential macro args - next if ($match =~ /^\s*\w+\s*$/); - if (!defined($herectx)) { - $herectx = $here . "\n"; - my $cnt = statement_rawlines($if_stat); - for (my $n = 0; $n < $cnt; $n++) { - my $rl = raw_line($linenr, $n); - $herectx .= $rl . "\n"; - last if $rl =~ /^[ \+].*\{/; - } - } - CHK("UNNECESSARY_PARENTHESES", - "Unnecessary parentheses around '$match'\n" . $herectx); - } - } - -#goto labels aren't indented, allow a single space however - if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and - !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { - if (WARN("INDENTED_LABEL", - "labels should not be indented\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/^(.)\s+/$1/; - } - } - -# check if a statement with a comma should be two statements like: -# foo = bar(), /* comma should be semicolon */ -# bar = baz(); - if (defined($stat) && - $stat =~ /^\+\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*,\s*(?:$Lval\s*$Assignment\s*)?$FuncArg\s*;\s*$/) { - my $cnt = statement_rawlines($stat); - my $herectx = get_stat_here($linenr, $cnt, $here); - WARN("SUSPECT_COMMA_SEMICOLON", - "Possible comma where semicolon could be used\n" . $herectx); - } - -# return is not a function - if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { - my $spacing = $1; - if ($perl_version_ok && - $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { - my $value = $1; - $value = deparenthesize($value); - if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) { - ERROR("RETURN_PARENTHESES", - "return is not a function, parentheses are not required\n" . $herecurr); - } - } elsif ($spacing !~ /\s+/) { - ERROR("SPACING", - "space required before the open parenthesis '('\n" . $herecurr); - } - } - -# unnecessary return in a void function -# at end-of-function, with the previous line a single leading tab, then return; -# and the line before that not a goto label target like "out:" - if ($sline =~ /^[ \+]}\s*$/ && - $prevline =~ /^\+\treturn\s*;\s*$/ && - $linenr >= 3 && - $lines[$linenr - 3] =~ /^[ +]/ && - $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) { - WARN("RETURN_VOID", - "void function return statements are not generally useful\n" . $hereprev); - } - -# if statements using unnecessary parentheses - ie: if ((foo == bar)) - if ($perl_version_ok && - $line =~ /\bif\s*((?:\(\s*){2,})/) { - my $openparens = $1; - my $count = $openparens =~ tr@\(@\(@; - my $msg = ""; - if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) { - my $comp = $4; #Not $1 because of $LvalOrFunc - $msg = " - maybe == should be = ?" if ($comp eq "=="); - WARN("UNNECESSARY_PARENTHESES", - "Unnecessary parentheses$msg\n" . $herecurr); - } - } - -# comparisons with a constant or upper case identifier on the left -# avoid cases like "foo + BAR < baz" -# only fix matches surrounded by parentheses to avoid incorrect -# conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" - if ($perl_version_ok && - $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { - my $lead = $1; - my $const = $2; - my $comp = $3; - my $to = $4; - my $newcomp = $comp; - if ($lead !~ /(?:$Operators|\.)\s*$/ && - $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ && - WARN("CONSTANT_COMPARISON", - "Comparisons should place the constant on the right side of the test\n" . $herecurr) && - $fix) { - if ($comp eq "<") { - $newcomp = ">"; - } elsif ($comp eq "<=") { - $newcomp = ">="; - } elsif ($comp eq ">") { - $newcomp = "<"; - } elsif ($comp eq ">=") { - $newcomp = "<="; - } - $fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/; - } - } - -# Return of what appears to be an errno should normally be negative - if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) { - my $name = $1; - if ($name ne 'EOF' && $name ne 'ERROR') { - WARN("USE_NEGATIVE_ERRNO", - "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr); - } - } - -# Need a space before open parenthesis after if, while etc - if ($line =~ /\b(if|while|for|switch)\(/) { - if (ERROR("SPACING", - "space required before the open parenthesis '('\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/\b(if|while|for|switch)\(/$1 \(/; - } - } - -# Check for illegal assignment in if conditional -- and check for trailing -# statements after the conditional. - if ($line =~ /do\s*(?!{)/) { - ($stat, $cond, $line_nr_next, $remain_next, $off_next) = - ctx_statement_block($linenr, $realcnt, 0) - if (!defined $stat); - my ($stat_next) = ctx_statement_block($line_nr_next, - $remain_next, $off_next); - $stat_next =~ s/\n./\n /g; - ##print "stat<$stat> stat_next<$stat_next>\n"; - - if ($stat_next =~ /^\s*while\b/) { - # If the statement carries leading newlines, - # then count those as offsets. - my ($whitespace) = - ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); - my $offset = - statement_rawlines($whitespace) - 1; - - $suppress_whiletrailers{$line_nr_next + - $offset} = 1; - } - } - if (!defined $suppress_whiletrailers{$linenr} && - defined($stat) && defined($cond) && - $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { - my ($s, $c) = ($stat, $cond); - - if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { - if (ERROR("ASSIGN_IN_IF", - "do not use assignment in if condition\n" . $herecurr) && - $fix && $perl_version_ok) { - if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) { - my $space = $1; - my $not = $2; - my $statement = $3; - my $assigned = $4; - my $test = $8; - my $against = $9; - my $brace = $15; - fix_delete_line($fixlinenr, $rawline); - fix_insert_line($fixlinenr, "$space$statement;"); - my $newline = "${space}if ("; - $newline .= '!' if defined($not); - $newline .= '(' if (defined $not && defined($test) && defined($against)); - $newline .= "$assigned"; - $newline .= " $test $against" if (defined($test) && defined($against)); - $newline .= ')' if (defined $not && defined($test) && defined($against)); - $newline .= ')'; - $newline .= " {" if (defined($brace)); - fix_insert_line($fixlinenr + 1, $newline); - } - } - } - - # Find out what is on the end of the line after the - # conditional. - substr($s, 0, length($c), ''); - $s =~ s/\n.*//g; - $s =~ s/$;//g; # Remove any comments - if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && - $c !~ /}\s*while\s*/) - { - # Find out how long the conditional actually is. - my @newlines = ($c =~ /\n/gs); - my $cond_lines = 1 + $#newlines; - my $stat_real = ''; - - $stat_real = raw_line($linenr, $cond_lines) - . "\n" if ($cond_lines); - if (defined($stat_real) && $cond_lines > 1) { - $stat_real = "[...]\n$stat_real"; - } - - ERROR("TRAILING_STATEMENTS", - "trailing statements should be on next line\n" . $herecurr . $stat_real); - } - } - -# Check for bitwise tests written as boolean - if ($line =~ / - (?: - (?:\[|\(|\&\&|\|\|) - \s*0[xX][0-9]+\s* - (?:\&\&|\|\|) - | - (?:\&\&|\|\|) - \s*0[xX][0-9]+\s* - (?:\&\&|\|\||\)|\]) - )/x) - { - WARN("HEXADECIMAL_BOOLEAN_TEST", - "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); - } - -# if and else should not have general statements after it - if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { - my $s = $1; - $s =~ s/$;//g; # Remove any comments - if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { - ERROR("TRAILING_STATEMENTS", - "trailing statements should be on next line\n" . $herecurr); - } - } -# if should not continue a brace - if ($line =~ /}\s*if\b/) { - ERROR("TRAILING_STATEMENTS", - "trailing statements should be on next line (or did you mean 'else if'?)\n" . - $herecurr); - } -# case and default should not have general statements after them - if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && - $line !~ /\G(?: - (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| - \s*return\s+ - )/xg) - { - ERROR("TRAILING_STATEMENTS", - "trailing statements should be on next line\n" . $herecurr); - } - - # Check for }<nl>else {, these must be at the same - # indent level to be relevant to each other. - if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ && - $previndent == $indent) { - if (ERROR("ELSE_AFTER_BRACE", - "else should follow close brace '}'\n" . $hereprev) && - $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { - fix_delete_line($fixlinenr - 1, $prevrawline); - fix_delete_line($fixlinenr, $rawline); - my $fixedline = $prevrawline; - $fixedline =~ s/}\s*$//; - if ($fixedline !~ /^\+\s*$/) { - fix_insert_line($fixlinenr, $fixedline); - } - $fixedline = $rawline; - $fixedline =~ s/^(.\s*)else/$1} else/; - fix_insert_line($fixlinenr, $fixedline); - } - } - - if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ && - $previndent == $indent) { - my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); - - # Find out what is on the end of the line after the - # conditional. - substr($s, 0, length($c), ''); - $s =~ s/\n.*//g; - - if ($s =~ /^\s*;/) { - if (ERROR("WHILE_AFTER_BRACE", - "while should follow close brace '}'\n" . $hereprev) && - $fix && $prevline =~ /^\+/ && $line =~ /^\+/) { - fix_delete_line($fixlinenr - 1, $prevrawline); - fix_delete_line($fixlinenr, $rawline); - my $fixedline = $prevrawline; - my $trailing = $rawline; - $trailing =~ s/^\+//; - $trailing = trim($trailing); - $fixedline =~ s/}\s*$/} $trailing/; - fix_insert_line($fixlinenr, $fixedline); - } - } - } - -#Specific variable tests - while ($line =~ m{($Constant|$Lval)}g) { - my $var = $1; - -#CamelCase - if ($var !~ /^$Constant$/ && - $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && -#Ignore Page<foo> variants - $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && -#Ignore SI style variants like nS, mV and dB -#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE) - $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ && -#Ignore some three character SI units explicitly, like MiB and KHz - $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) { - while ($var =~ m{($Ident)}g) { - my $word = $1; - next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/); - if ($check) { - seed_camelcase_includes(); - if (!$file && !$camelcase_file_seeded) { - seed_camelcase_file($realfile); - $camelcase_file_seeded = 1; - } - } - if (!defined $camelcase{$word}) { - $camelcase{$word} = 1; - CHK("CAMELCASE", - "Avoid CamelCase: <$word>\n" . $herecurr); - } - } - } - } - -#no spaces allowed after \ in define - if ($line =~ /\#\s*define.*\\\s+$/) { - if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION", - "Whitespace after \\ makes next lines useless\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\s+$//; - } - } - -# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes -# itself <asm/foo.h> (uses RAW line) - if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { - my $file = "$1.h"; - my $checkfile = "include/linux/$file"; - if (-f "$root/$checkfile" && - $realfile ne $checkfile && - $1 !~ /$allowed_asm_includes/) - { - my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`; - if ($asminclude > 0) { - if ($realfile =~ m{^arch/}) { - CHK("ARCH_INCLUDE_LINUX", - "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); - } else { - WARN("INCLUDE_LINUX", - "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); - } - } - } - } - -# multi-statement macros should be enclosed in a do while loop, grab the -# first statement and ensure its the whole macro if its not enclosed -# in a known good container - if ($realfile !~ m@/vmlinux.lds.h$@ && - $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { - my $ln = $linenr; - my $cnt = $realcnt; - my ($off, $dstat, $dcond, $rest); - my $ctx = ''; - my $has_flow_statement = 0; - my $has_arg_concat = 0; - ($dstat, $dcond, $ln, $cnt, $off) = - ctx_statement_block($linenr, $realcnt, 0); - $ctx = $dstat; - #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; - #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; - - $has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/); - $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); - - $dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//; - my $define_args = $1; - my $define_stmt = $dstat; - my @def_args = (); - - if (defined $define_args && $define_args ne "") { - $define_args = substr($define_args, 1, length($define_args) - 2); - $define_args =~ s/\s*//g; - $define_args =~ s/\\\+?//g; - @def_args = split(",", $define_args); - } - - $dstat =~ s/$;//g; - $dstat =~ s/\\\n.//g; - $dstat =~ s/^\s*//s; - $dstat =~ s/\s*$//s; - - # Flatten any parentheses and braces - while ($dstat =~ s/\([^\(\)]*\)/1u/ || - $dstat =~ s/\{[^\{\}]*\}/1u/ || - $dstat =~ s/.\[[^\[\]]*\]/1u/) - { - } - - # Flatten any obvious string concatenation. - while ($dstat =~ s/($String)\s*$Ident/$1/ || - $dstat =~ s/$Ident\s*($String)/$1/) - { - } - - # Make asm volatile uses seem like a generic function - $dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; - - my $exceptions = qr{ - $Declare| - module_param_named| - MODULE_PARM_DESC| - DECLARE_PER_CPU| - DEFINE_PER_CPU| - __typeof__\(| - union| - struct| - \.$Ident\s*=\s*| - ^\"|\"$| - ^\[ - }x; - #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; - - $ctx =~ s/\n*$//; - my $stmt_cnt = statement_rawlines($ctx); - my $herectx = get_stat_here($linenr, $stmt_cnt, $here); - - if ($dstat ne '' && - $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), - $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); - $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz - $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ && # character constants - $dstat !~ /$exceptions/ && - $dstat !~ /^\.$Ident\s*=/ && # .foo = - $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo - $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) - $dstat !~ /^while\s*$Constant\s*$Constant\s*$/ && # while (...) {...} - $dstat !~ /^for\s*$Constant$/ && # for (...) - $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() - $dstat !~ /^do\s*{/ && # do {... - $dstat !~ /^\(\{/ && # ({... - $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/) - { - if ($dstat =~ /^\s*if\b/) { - ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", - "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); - } elsif ($dstat =~ /;/) { - ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", - "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); - } else { - ERROR("COMPLEX_MACRO", - "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); - } - - } - - # Make $define_stmt single line, comment-free, etc - my @stmt_array = split('\n', $define_stmt); - my $first = 1; - $define_stmt = ""; - foreach my $l (@stmt_array) { - $l =~ s/\\$//; - if ($first) { - $define_stmt = $l; - $first = 0; - } elsif ($l =~ /^[\+ ]/) { - $define_stmt .= substr($l, 1); - } - } - $define_stmt =~ s/$;//g; - $define_stmt =~ s/\s+/ /g; - $define_stmt = trim($define_stmt); - -# check if any macro arguments are reused (ignore '...' and 'type') - foreach my $arg (@def_args) { - next if ($arg =~ /\.\.\./); - next if ($arg =~ /^type$/i); - my $tmp_stmt = $define_stmt; - $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; - $tmp_stmt =~ s/\#+\s*$arg\b//g; - $tmp_stmt =~ s/\b$arg\s*\#\#//g; - my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; - if ($use_cnt > 1) { - CHK("MACRO_ARG_REUSE", - "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); - } -# check if any macro arguments may have other precedence issues - if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && - ((defined($1) && $1 ne ',') || - (defined($2) && $2 ne ','))) { - CHK("MACRO_ARG_PRECEDENCE", - "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx"); - } - } - -# check for macros with flow control, but without ## concatenation -# ## concatenation is commonly a macro that defines a function so ignore those - if ($has_flow_statement && !$has_arg_concat) { - my $cnt = statement_rawlines($ctx); - my $herectx = get_stat_here($linenr, $cnt, $here); - - WARN("MACRO_WITH_FLOW_CONTROL", - "Macros with flow control statements should be avoided\n" . "$herectx"); - } - -# check for line continuations outside of #defines, preprocessor #, and asm - - } else { - if ($prevline !~ /^..*\\$/ && - $line !~ /^\+\s*\#.*\\$/ && # preprocessor - $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm - $line =~ /^\+.*\\$/) { - WARN("LINE_CONTINUATIONS", - "Avoid unnecessary line continuations\n" . $herecurr); - } - } - -# do {} while (0) macro tests: -# single-statement macros do not need to be enclosed in do while (0) loop, -# macro should not end with a semicolon - if ($perl_version_ok && - $realfile !~ m@/vmlinux.lds.h$@ && - $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { - my $ln = $linenr; - my $cnt = $realcnt; - my ($off, $dstat, $dcond, $rest); - my $ctx = ''; - ($dstat, $dcond, $ln, $cnt, $off) = - ctx_statement_block($linenr, $realcnt, 0); - $ctx = $dstat; - - $dstat =~ s/\\\n.//g; - $dstat =~ s/$;/ /g; - - if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { - my $stmts = $2; - my $semis = $3; - - $ctx =~ s/\n*$//; - my $cnt = statement_rawlines($ctx); - my $herectx = get_stat_here($linenr, $cnt, $here); - - if (($stmts =~ tr/;/;/) == 1 && - $stmts !~ /^\s*(if|while|for|switch)\b/) { - WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", - "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); - } - if (defined $semis && $semis ne "") { - WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", - "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); - } - } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) { - $ctx =~ s/\n*$//; - my $cnt = statement_rawlines($ctx); - my $herectx = get_stat_here($linenr, $cnt, $here); - - WARN("TRAILING_SEMICOLON", - "macros should not use a trailing semicolon\n" . "$herectx"); - } - } - -# check for redundant bracing round if etc - if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { - my ($level, $endln, @chunks) = - ctx_statement_full($linenr, $realcnt, 1); - #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; - #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; - if ($#chunks > 0 && $level == 0) { - my @allowed = (); - my $allow = 0; - my $seen = 0; - my $herectx = $here . "\n"; - my $ln = $linenr - 1; - for my $chunk (@chunks) { - my ($cond, $block) = @{$chunk}; - - # If the condition carries leading newlines, then count those as offsets. - my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); - my $offset = statement_rawlines($whitespace) - 1; - - $allowed[$allow] = 0; - #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; - - # We have looked at and allowed this specific line. - $suppress_ifbraces{$ln + $offset} = 1; - - $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; - $ln += statement_rawlines($block) - 1; - - substr($block, 0, length($cond), ''); - - $seen++ if ($block =~ /^\s*{/); - - #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; - if (statement_lines($cond) > 1) { - #print "APW: ALLOWED: cond<$cond>\n"; - $allowed[$allow] = 1; - } - if ($block =~/\b(?:if|for|while)\b/) { - #print "APW: ALLOWED: block<$block>\n"; - $allowed[$allow] = 1; - } - if (statement_block_size($block) > 1) { - #print "APW: ALLOWED: lines block<$block>\n"; - $allowed[$allow] = 1; - } - $allow++; - } - if ($seen) { - my $sum_allowed = 0; - foreach (@allowed) { - $sum_allowed += $_; - } - if ($sum_allowed == 0) { - WARN("BRACES", - "braces {} are not necessary for any arm of this statement\n" . $herectx); - } elsif ($sum_allowed != $allow && - $seen != $allow) { - CHK("BRACES", - "braces {} should be used on all arms of this statement\n" . $herectx); - } - } - } - } - if (!defined $suppress_ifbraces{$linenr - 1} && - $line =~ /\b(if|while|for|else)\b/) { - my $allowed = 0; - - # Check the pre-context. - if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { - #print "APW: ALLOWED: pre<$1>\n"; - $allowed = 1; - } - - my ($level, $endln, @chunks) = - ctx_statement_full($linenr, $realcnt, $-[0]); - - # Check the condition. - my ($cond, $block) = @{$chunks[0]}; - #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; - if (defined $cond) { - substr($block, 0, length($cond), ''); - } - if (statement_lines($cond) > 1) { - #print "APW: ALLOWED: cond<$cond>\n"; - $allowed = 1; - } - if ($block =~/\b(?:if|for|while)\b/) { - #print "APW: ALLOWED: block<$block>\n"; - $allowed = 1; - } - if (statement_block_size($block) > 1) { - #print "APW: ALLOWED: lines block<$block>\n"; - $allowed = 1; - } - # Check the post-context. - if (defined $chunks[1]) { - my ($cond, $block) = @{$chunks[1]}; - if (defined $cond) { - substr($block, 0, length($cond), ''); - } - if ($block =~ /^\s*\{/) { - #print "APW: ALLOWED: chunk-1 block<$block>\n"; - $allowed = 1; - } - } - if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { - my $cnt = statement_rawlines($block); - my $herectx = get_stat_here($linenr, $cnt, $here); - - WARN("BRACES", - "braces {} are not necessary for single statement blocks\n" . $herectx); - } - } - -# check for single line unbalanced braces - if ($sline =~ /^.\s*\}\s*else\s*$/ || - $sline =~ /^.\s*else\s*\{\s*$/) { - CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr); - } - -# check for unnecessary blank lines around braces - if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { - if (CHK("BRACES", - "Blank lines aren't necessary before a close brace '}'\n" . $hereprev) && - $fix && $prevrawline =~ /^\+/) { - fix_delete_line($fixlinenr - 1, $prevrawline); - } - } - if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { - if (CHK("BRACES", - "Blank lines aren't necessary after an open brace '{'\n" . $hereprev) && - $fix) { - fix_delete_line($fixlinenr, $rawline); - } - } - -# no volatiles please - my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; - if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { - WARN("VOLATILE", - "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr); - } - -# Check for user-visible strings broken across lines, which breaks the ability -# to grep for the string. Make exceptions when the previous string ends in a -# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{' -# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value - if ($line =~ /^\+\s*$String/ && - $prevline =~ /"\s*$/ && - $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) { - if (WARN("SPLIT_STRING", - "quoted string split across lines\n" . $hereprev) && - $fix && - $prevrawline =~ /^\+.*"\s*$/ && - $last_coalesced_string_linenr != $linenr - 1) { - my $extracted_string = get_quoted_string($line, $rawline); - my $comma_close = ""; - if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) { - $comma_close = $1; - } - - fix_delete_line($fixlinenr - 1, $prevrawline); - fix_delete_line($fixlinenr, $rawline); - my $fixedline = $prevrawline; - $fixedline =~ s/"\s*$//; - $fixedline .= substr($extracted_string, 1) . trim($comma_close); - fix_insert_line($fixlinenr - 1, $fixedline); - $fixedline = $rawline; - $fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//; - if ($fixedline !~ /\+\s*$/) { - fix_insert_line($fixlinenr, $fixedline); - } - $last_coalesced_string_linenr = $linenr; - } - } - -# check for missing a space in a string concatenation - if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) { - WARN('MISSING_SPACE', - "break quoted strings at a space character\n" . $hereprev); - } - -# check for an embedded function name in a string when the function is known -# This does not work very well for -f --file checking as it depends on patch -# context providing the function name or a single line form for in-file -# function declarations - if ($line =~ /^\+.*$String/ && - defined($context_function) && - get_quoted_string($line, $rawline) =~ /\b$context_function\b/ && - length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) { - WARN("EMBEDDED_FUNCTION_NAME", - "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr); - } - -# check for spaces before a quoted newline - if ($rawline =~ /^.*\".*\s\\n/) { - if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", - "unnecessary whitespace before a quoted newline\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; - } - - } - -# concatenated string without spaces between elements - if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { - if (CHK("CONCATENATED_STRING", - "Concatenated strings should use spaces between elements\n" . $herecurr) && - $fix) { - while ($line =~ /($String)/g) { - my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); - $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; - $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; - } - } - } - -# uncoalesced string fragments - if ($line =~ /$String\s*"/) { - if (WARN("STRING_FRAGMENTS", - "Consecutive strings are generally better as a single string\n" . $herecurr) && - $fix) { - while ($line =~ /($String)(?=\s*")/g) { - my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); - $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; - } - } - } - -# check for non-standard and hex prefixed decimal printf formats - my $show_L = 1; #don't show the same defect twice - my $show_Z = 1; - while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { - my $string = substr($rawline, $-[1], $+[1] - $-[1]); - $string =~ s/%%/__/g; - # check for %L - if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) { - WARN("PRINTF_L", - "\%L$1 is non-standard C, use %ll$1\n" . $herecurr); - $show_L = 0; - } - # check for %Z - if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) { - WARN("PRINTF_Z", - "%Z$1 is non-standard C, use %z$1\n" . $herecurr); - $show_Z = 0; - } - # check for 0x<decimal> - if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) { - ERROR("PRINTF_0XDECIMAL", - "Prefixing 0x with decimal output is defective\n" . $herecurr); - } - } - -# check for line continuations in quoted strings with odd counts of " - if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) { - WARN("LINE_CONTINUATIONS", - "Avoid line continuations in quoted strings\n" . $herecurr); - } - -# warn about #if 0 - if ($line =~ /^.\s*\#\s*if\s+0\b/) { - WARN("IF_0", - "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); - } - -# warn about #if 1 - if ($line =~ /^.\s*\#\s*if\s+1\b/) { - WARN("IF_1", - "Consider removing the #if 1 and its #endif\n" . $herecurr); - } - -# check for needless "if (<foo>) fn(<foo>)" uses - if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { - my $tested = quotemeta($1); - my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;'; - if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) { - my $func = $1; - if (WARN('NEEDLESS_IF', - "$func(NULL) is safe and this check is probably not required\n" . $hereprev) && - $fix) { - my $do_fix = 1; - my $leading_tabs = ""; - my $new_leading_tabs = ""; - if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) { - $leading_tabs = $1; - } else { - $do_fix = 0; - } - if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) { - $new_leading_tabs = $1; - if (length($leading_tabs) + 1 ne length($new_leading_tabs)) { - $do_fix = 0; - } - } else { - $do_fix = 0; - } - if ($do_fix) { - fix_delete_line($fixlinenr - 1, $prevrawline); - $fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/; - } - } - } - } - -# check for unnecessary "Out of Memory" messages - if ($line =~ /^\+.*\b$logFunctions\s*\(/ && - $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ && - (defined $1 || defined $3) && - $linenr > 3) { - my $testval = $2; - my $testline = $lines[$linenr - 3]; - - my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); -# print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); - - if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && - $s !~ /\b__GFP_NOWARN\b/ ) { - WARN("OOM_MESSAGE", - "Possible unnecessary 'out of memory' message\n" . $hereprev); - } - } - -# check for logging functions with KERN_<LEVEL> - if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ && - $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) { - my $level = $1; - if (WARN("UNNECESSARY_KERN_LEVEL", - "Possible unnecessary $level\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\s*$level\s*//; - } - } - -# check for logging continuations - if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) { - WARN("LOGGING_CONTINUATION", - "Avoid logging continuation uses where feasible\n" . $herecurr); - } - -# check for mask then right shift without a parentheses - if ($perl_version_ok && - $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && - $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so - WARN("MASK_THEN_SHIFT", - "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr); - } - -# check for pointer comparisons to NULL - if ($perl_version_ok) { - while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { - my $val = $1; - my $equal = "!"; - $equal = "" if ($4 eq "!="); - if (CHK("COMPARISON_TO_NULL", - "Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/; - } - } - } - -# check for bad placement of section $InitAttribute (e.g.: __initdata) - if ($line =~ /(\b$InitAttribute\b)/) { - my $attr = $1; - if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) { - my $ptr = $1; - my $var = $2; - if ((($ptr =~ /\b(union|struct)\s+$attr\b/ && - ERROR("MISPLACED_INIT", - "$attr should be placed after $var\n" . $herecurr)) || - ($ptr !~ /\b(union|struct)\s+$attr\b/ && - WARN("MISPLACED_INIT", - "$attr should be placed after $var\n" . $herecurr))) && - $fix) { - $fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e; - } - } - } - -# check for $InitAttributeData (ie: __initdata) with const - if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) { - my $attr = $1; - $attr =~ /($InitAttributePrefix)(.*)/; - my $attr_prefix = $1; - my $attr_type = $2; - if (ERROR("INIT_ATTRIBUTE", - "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/$InitAttributeData/${attr_prefix}initconst/; - } - } - -# check for $InitAttributeConst (ie: __initconst) without const - if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) { - my $attr = $1; - if (ERROR("INIT_ATTRIBUTE", - "Use of $attr requires a separate use of const\n" . $herecurr) && - $fix) { - my $lead = $fixed[$fixlinenr] =~ - /(^\+\s*(?:static\s+))/; - $lead = rtrim($1); - $lead = "$lead " if ($lead !~ /^\+$/); - $lead = "${lead}const "; - $fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/; - } - } - -# check for __read_mostly with const non-pointer (should just be const) - if ($line =~ /\b__read_mostly\b/ && - $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) { - if (ERROR("CONST_READ_MOSTLY", - "Invalid use of __read_mostly with const type\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\s+__read_mostly\b//; - } - } - -# don't use __constant_<foo> functions outside of include/uapi/ - if ($realfile !~ m@^include/uapi/@ && - $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) { - my $constant_func = $1; - my $func = $constant_func; - $func =~ s/^__constant_//; - if (WARN("CONSTANT_CONVERSION", - "$constant_func should be $func\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g; - } - } - -# prefer usleep_range over udelay - if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { - my $delay = $1; - # ignore udelay's < 10, however - if (! ($delay < 10) ) { - CHK("USLEEP_RANGE", - "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); - } - if ($delay > 2000) { - WARN("LONG_UDELAY", - "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr); - } - } - -# warn about unexpectedly long msleep's - if ($line =~ /\bmsleep\s*\((\d+)\);/) { - if ($1 < 20) { - WARN("MSLEEP", - "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); - } - } - -# check for comparisons of jiffies - if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { - WARN("JIFFIES_COMPARISON", - "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); - } - -# check for comparisons of get_jiffies_64() - if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { - WARN("JIFFIES_COMPARISON", - "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); - } - -# warn about #ifdefs in C files -# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { -# print "#ifdef in C files should be avoided\n"; -# print "$herecurr"; -# $clean = 0; -# } - -# warn about spacing in #ifdefs - if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { - if (ERROR("SPACING", - "exactly one space required after that #$1\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ - s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; - } - - } - -# check for spinlock_t definitions without a comment. - if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || - $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { - my $which = $1; - if (!ctx_has_comment($first_line, $linenr)) { - CHK("UNCOMMENTED_DEFINITION", - "$1 definition without comment\n" . $herecurr); - } - } -# check for memory barriers without a comment. - - my $barriers = qr{ - mb| - rmb| - wmb - }x; - my $barrier_stems = qr{ - mb__before_atomic| - mb__after_atomic| - store_release| - load_acquire| - store_mb| - (?:$barriers) - }x; - my $all_barriers = qr{ - (?:$barriers)| - smp_(?:$barrier_stems)| - virt_(?:$barrier_stems) - }x; - - if ($line =~ /\b(?:$all_barriers)\s*\(/) { - if (!ctx_has_comment($first_line, $linenr)) { - WARN("MEMORY_BARRIER", - "memory barrier without comment\n" . $herecurr); - } - } - - my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x; - - if ($realfile !~ m@^include/asm-generic/@ && - $realfile !~ m@/barrier\.h$@ && - $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ && - $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) { - WARN("MEMORY_BARRIER", - "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr); - } - -# check for waitqueue_active without a comment. - if ($line =~ /\bwaitqueue_active\s*\(/) { - if (!ctx_has_comment($first_line, $linenr)) { - WARN("WAITQUEUE_ACTIVE", - "waitqueue_active without comment\n" . $herecurr); - } - } - -# check for data_race without a comment. - if ($line =~ /\bdata_race\s*\(/) { - if (!ctx_has_comment($first_line, $linenr)) { - WARN("DATA_RACE", - "data_race without comment\n" . $herecurr); - } - } - -# check of hardware specific defines - if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { - CHK("ARCH_DEFINES", - "architecture specific defines should be avoided\n" . $herecurr); - } - -# check that the storage class is not after a type - if ($line =~ /\b($Type)\s+($Storage)\b/) { - WARN("STORAGE_CLASS", - "storage class '$2' should be located before type '$1'\n" . $herecurr); - } -# Check that the storage class is at the beginning of a declaration - if ($line =~ /\b$Storage\b/ && - $line !~ /^.\s*$Storage/ && - $line =~ /^.\s*(.+?)\$Storage\s/ && - $1 !~ /[\,\)]\s*$/) { - WARN("STORAGE_CLASS", - "storage class should be at the beginning of the declaration\n" . $herecurr); - } - -# check the location of the inline attribute, that it is between -# storage class and type. - if ($line =~ /\b$Type\s+$Inline\b/ || - $line =~ /\b$Inline\s+$Storage\b/) { - ERROR("INLINE_LOCATION", - "inline keyword should sit between storage class and type\n" . $herecurr); - } - -# Check for __inline__ and __inline, prefer inline - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b(__inline__|__inline)\b/) { - if (WARN("INLINE", - "plain inline is preferred over $1\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; - - } - } - -# Check for __attribute__ packed, prefer __packed - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { - WARN("PREFER_PACKED", - "__packed is preferred over __attribute__((packed))\n" . $herecurr); - } - -# Check for __attribute__ aligned, prefer __aligned - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { - WARN("PREFER_ALIGNED", - "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); - } - -# Check for __attribute__ section, prefer __section - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { - my $old = substr($rawline, $-[1], $+[1] - $-[1]); - my $new = substr($old, 1, -1); - if (WARN("PREFER_SECTION", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; - } - } - -# Check for __attribute__ format(printf, prefer __printf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { - if (WARN("PREFER_PRINTF", - "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; - - } - } - -# Check for __attribute__ format(scanf, prefer __scanf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { - if (WARN("PREFER_SCANF", - "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; - } - } - -# Check for __attribute__ weak, or __weak declarations (may have link issues) - if ($perl_version_ok && - $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && - ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || - $line =~ /\b__weak\b/)) { - ERROR("WEAK_DECLARATION", - "Using weak declarations can have unintended link defects\n" . $herecurr); - } - -# check for c99 types like uint8_t used outside of uapi/ and tools/ - if ($realfile !~ m@\binclude/uapi/@ && - $realfile !~ m@\btools/@ && - $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) { - my $type = $1; - if ($type =~ /\b($typeC99Typedefs)\b/) { - $type = $1; - my $kernel_type = 'u'; - $kernel_type = 's' if ($type =~ /^_*[si]/); - $type =~ /(\d+)/; - $kernel_type .= $1; - if (CHK("PREFER_KERNEL_TYPES", - "Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/; - } - } - } - -# check for cast of C90 native int or longer types constants - if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) { - my $cast = $1; - my $const = $2; - if (WARN("TYPECAST_INT_CONSTANT", - "Unnecessary typecast of c90 int constant\n" . $herecurr) && - $fix) { - my $suffix = ""; - my $newconst = $const; - $newconst =~ s/${Int_type}$//; - $suffix .= 'U' if ($cast =~ /\bunsigned\b/); - if ($cast =~ /\blong\s+long\b/) { - $suffix .= 'LL'; - } elsif ($cast =~ /\blong\b/) { - $suffix .= 'L'; - } - $fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/; - } - } - -# check for sizeof(&) - if ($line =~ /\bsizeof\s*\(\s*\&/) { - WARN("SIZEOF_ADDRESS", - "sizeof(& should be avoided\n" . $herecurr); - } - -# check for sizeof without parenthesis - if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { - if (WARN("SIZEOF_PARENTHESIS", - "sizeof $1 should be sizeof($1)\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex; - } - } - -# check for struct spinlock declarations - if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { - WARN("USE_SPINLOCK_T", - "struct spinlock should be spinlock_t\n" . $herecurr); - } - -# check for seq_printf uses that could be seq_puts - if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) { - my $fmt = get_quoted_string($line, $rawline); - $fmt =~ s/%%//g; - if ($fmt !~ /%/) { - if (WARN("PREFER_SEQ_PUTS", - "Prefer seq_puts to seq_printf\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/; - } - } - } - -# check for vsprintf extension %p<foo> misuses - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && - $1 !~ /^_*volatile_*$/) { - my $stat_real; - - my $lc = $stat =~ tr@\n@@; - $lc = $lc + $linenr; - for (my $count = $linenr; $count <= $lc; $count++) { - my $specifier; - my $extension; - my $qualifier; - my $bad_specifier = ""; - my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); - $fmt =~ s/%%//g; - - while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { - $specifier = $1; - $extension = $2; - $qualifier = $3; - if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ || - ($extension eq "f" && - defined $qualifier && $qualifier !~ /^w/)) { - $bad_specifier = $specifier; - last; - } - if ($extension eq "x" && !defined($stat_real)) { - if (!defined($stat_real)) { - $stat_real = get_stat_real($linenr, $lc); - } - WARN("VSPRINTF_SPECIFIER_PX", - "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n"); - } - } - if ($bad_specifier ne "") { - my $stat_real = get_stat_real($linenr, $lc); - my $ext_type = "Invalid"; - my $use = ""; - if ($bad_specifier =~ /p[Ff]/) { - $use = " - use %pS instead"; - $use =~ s/pS/ps/ if ($bad_specifier =~ /pf/); - } - - WARN("VSPRINTF_POINTER_EXTENSION", - "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n"); - } - } - } - -# Check for misused memsets - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { - - my $ms_addr = $2; - my $ms_val = $7; - my $ms_size = $12; - - if ($ms_size =~ /^(0x|)0$/i) { - ERROR("MEMSET", - "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); - } elsif ($ms_size =~ /^(0x|)1$/i) { - WARN("MEMSET", - "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); - } - } - -# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) -# if ($perl_version_ok && -# defined $stat && -# $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { -# if (WARN("PREFER_ETHER_ADDR_COPY", -# "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") && -# $fix) { -# $fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/; -# } -# } - -# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) -# if ($perl_version_ok && -# defined $stat && -# $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { -# WARN("PREFER_ETHER_ADDR_EQUAL", -# "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n") -# } - -# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr -# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr -# if ($perl_version_ok && -# defined $stat && -# $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { -# -# my $ms_val = $7; -# -# if ($ms_val =~ /^(?:0x|)0+$/i) { -# if (WARN("PREFER_ETH_ZERO_ADDR", -# "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") && -# $fix) { -# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/; -# } -# } elsif ($ms_val =~ /^(?:0xff|255)$/i) { -# if (WARN("PREFER_ETH_BROADCAST_ADDR", -# "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") && -# $fix) { -# $fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/; -# } -# } -# } - -# typecasts on min/max could be min_t/max_t - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { - if (defined $2 || defined $7) { - my $call = $1; - my $cast1 = deparenthesize($2); - my $arg1 = $3; - my $cast2 = deparenthesize($7); - my $arg2 = $8; - my $cast; - - if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { - $cast = "$cast1 or $cast2"; - } elsif ($cast1 ne "") { - $cast = $cast1; - } else { - $cast = $cast2; - } - WARN("MINMAX", - "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); - } - } - -# check usleep_range arguments - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { - my $min = $1; - my $max = $7; - if ($min eq $max) { - WARN("USLEEP_RANGE", - "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); - } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && - $min > $max) { - WARN("USLEEP_RANGE", - "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); - } - } - -# check for naked sscanf - if ($perl_version_ok && - defined $stat && - $line =~ /\bsscanf\b/ && - ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && - $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ && - $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) { - my $lc = $stat =~ tr@\n@@; - $lc = $lc + $linenr; - my $stat_real = get_stat_real($linenr, $lc); - WARN("NAKED_SSCANF", - "unchecked sscanf return value\n" . "$here\n$stat_real\n"); - } - -# check for simple sscanf that should be kstrto<foo> - if ($perl_version_ok && - defined $stat && - $line =~ /\bsscanf\b/) { - my $lc = $stat =~ tr@\n@@; - $lc = $lc + $linenr; - my $stat_real = get_stat_real($linenr, $lc); - if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) { - my $format = $6; - my $count = $format =~ tr@%@%@; - if ($count == 1 && - $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) { - WARN("SSCANF_TO_KSTRTO", - "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n"); - } - } - } - -# check for new externs in .h files. - if ($realfile =~ /\.h$/ && - $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) { - if (CHK("AVOID_EXTERNS", - "extern prototypes should be avoided in .h files\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/; - } - } - -# check for new externs in .c files. - if ($realfile =~ /\.c$/ && defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) - { - my $function_name = $1; - my $paren_space = $2; - - my $s = $stat; - if (defined $cond) { - substr($s, 0, length($cond), ''); - } - if ($s =~ /^\s*;/) - { - WARN("AVOID_EXTERNS", - "externs should be avoided in .c files\n" . $herecurr); - } - - if ($paren_space =~ /\n/) { - WARN("FUNCTION_ARGUMENTS", - "arguments for function declarations should follow identifier\n" . $herecurr); - } - - } elsif ($realfile =~ /\.c$/ && defined $stat && - $stat =~ /^.\s*extern\s+/) - { - WARN("AVOID_EXTERNS", - "externs should be avoided in .c files\n" . $herecurr); - } - -# check for function declarations that have arguments without identifier names - if (defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s && - $1 ne "void") { - my $args = trim($1); - while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) { - my $arg = trim($1); - if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) { - WARN("FUNCTION_ARGUMENTS", - "function definition argument '$arg' should also have an identifier name\n" . $herecurr); - } - } - } - -# check for function definitions - if ($perl_version_ok && - defined $stat && - $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { - $context_function = $1; - -# check for multiline function definition with misplaced open brace - my $ok = 0; - my $cnt = statement_rawlines($stat); - my $herectx = $here . "\n"; - for (my $n = 0; $n < $cnt; $n++) { - my $rl = raw_line($linenr, $n); - $herectx .= $rl . "\n"; - $ok = 1 if ($rl =~ /^[ \+]\{/); - $ok = 1 if ($rl =~ /\{/ && $n == 0); - last if $rl =~ /^[ \+].*\{/; - } - if (!$ok) { - ERROR("OPEN_BRACE", - "open brace '{' following function definitions go on the next line\n" . $herectx); - } - } - -# checks for new __setup's - if ($rawline =~ /\b__setup\("([^"]*)"/) { - my $name = $1; - - if (!grep(/$name/, @setup_docs)) { - CHK("UNDOCUMENTED_SETUP", - "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr); - } - } - -# check for pointless casting of alloc functions - if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { - WARN("UNNECESSARY_CASTS", - "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); - } - -# alloc style -# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) - if ($perl_version_ok && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { - CHK("ALLOC_SIZEOF_STRUCT", - "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); - } - -# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { - my $oldfunc = $3; - my $a1 = $4; - my $a2 = $10; - my $newfunc = "kmalloc_array"; - $newfunc = "kcalloc" if ($oldfunc eq "kzalloc"); - my $r1 = $a1; - my $r2 = $a2; - if ($a1 =~ /^sizeof\s*\S/) { - $r1 = $a2; - $r2 = $a1; - } - if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ && - !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) { - my $cnt = statement_rawlines($stat); - my $herectx = get_stat_here($linenr, $cnt, $here); - - if (WARN("ALLOC_WITH_MULTIPLY", - "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) && - $cnt == 1 && - $fix) { - $fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e; - } - } - } - -# check for krealloc arg reuse - if ($perl_version_ok && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && - $1 eq $3) { - WARN("KREALLOC_ARG_REUSE", - "Reusing the krealloc arg is almost always a bug\n" . $herecurr); - } - -# check for alloc argument mismatch - if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { - WARN("ALLOC_ARRAY_ARGS", - "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); - } - -# check for multiple semicolons - if ($line =~ /;\s*;\s*$/) { - if (WARN("ONE_SEMICOLON", - "Statements terminations use 1 semicolon\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g; - } - } - -# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi - if ($realfile !~ m@^include/uapi/@ && - $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) { - my $ull = ""; - $ull = "_ULL" if (defined($1) && $1 =~ /ll/i); - if (CHK("BIT_MACRO", - "Prefer using the BIT$ull macro\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/; - } - } - -# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too) - if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) { - WARN("IS_ENABLED_CONFIG", - "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr); - } - -# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE - if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { - my $config = $1; - if (WARN("PREFER_IS_ENABLED", - "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; - } - } - -# check for /* fallthrough */ like comment, prefer fallthrough; - my @fallthroughs = ( - 'fallthrough', - '@fallthrough@', - 'lint -fallthrough[ \t]*', - 'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)', - '(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?', - 'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', - 'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?', - ); - if ($raw_comment ne '') { - foreach my $ft (@fallthroughs) { - if ($raw_comment =~ /$ft/) { - my $msg_level = \&WARN; - $msg_level = \&CHK if ($file); - &{$msg_level}("PREFER_FALLTHROUGH", - "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr); - last; - } - } - } - -# check for switch/default statements without a break; - if ($perl_version_ok && - defined $stat && - $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { - my $cnt = statement_rawlines($stat); - my $herectx = get_stat_here($linenr, $cnt, $here); - - WARN("DEFAULT_NO_BREAK", - "switch default: should use break\n" . $herectx); - } - -# check for gcc specific __FUNCTION__ - if ($line =~ /\b__FUNCTION__\b/) { - if (WARN("USE_FUNC", - "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g; - } - } - -# check for uses of __DATE__, __TIME__, __TIMESTAMP__ - while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) { - ERROR("DATE_TIME", - "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr); - } - -# check for use of yield() - if ($line =~ /\byield\s*\(\s*\)/) { - WARN("YIELD", - "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); - } - -# check for comparisons against true and false - if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { - my $lead = $1; - my $arg = $2; - my $test = $3; - my $otype = $4; - my $trail = $5; - my $op = "!"; - - ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); - - my $type = lc($otype); - if ($type =~ /^(?:true|false)$/) { - if (("$test" eq "==" && "$type" eq "true") || - ("$test" eq "!=" && "$type" eq "false")) { - $op = ""; - } - - CHK("BOOL_COMPARISON", - "Using comparison to $otype is error prone\n" . $herecurr); - -## maybe suggesting a correct construct would better -## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); - - } - } - -# check for semaphores initialized locked - if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { - WARN("CONSIDER_COMPLETION", - "consider using a completion\n" . $herecurr); - } - -# recommend kstrto* over simple_strto* and strict_strto* - if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { - WARN("CONSIDER_KSTRTO", - "$1 is obsolete, use k$3 instead\n" . $herecurr); - } - -# check for __initcall(), use device_initcall() explicitly or more appropriate function please - if ($line =~ /^.\s*__initcall\s*\(/) { - WARN("USE_DEVICE_INITCALL", - "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); - } - -# check for spin_is_locked(), suggest lockdep instead - if ($line =~ /\bspin_is_locked\(/) { - WARN("USE_LOCKDEP", - "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); - } - -# check for deprecated apis - if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { - my $deprecated_api = $1; - my $new_api = $deprecated_apis{$deprecated_api}; - WARN("DEPRECATED_API", - "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); - } - -# check for various structs that are normally const (ops, kgdb, device_tree) -# and avoid what seem like struct definitions 'struct foo {' - if (defined($const_structs) && - $line !~ /\bconst\b/ && - $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) { - WARN("CONST_STRUCT", - "struct $1 should normally be const\n" . $herecurr); - } - -# use of NR_CPUS is usually wrong -# ignore definitions of NR_CPUS and usage to define arrays as likely right - if ($line =~ /\bNR_CPUS\b/ && - $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && - $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && - $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && - $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && - $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) - { - WARN("NR_CPUS", - "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); - } - -# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong. - if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) { - ERROR("DEFINE_ARCH_HAS", - "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr); - } - -# likely/unlikely comparisons similar to "(likely(foo) > 0)" - if ($perl_version_ok && - $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { - WARN("LIKELY_MISUSE", - "Using $1 should generally have parentheses around the comparison\n" . $herecurr); - } - -# nested likely/unlikely calls - if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { - WARN("LIKELY_MISUSE", - "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); - } - -# whine mightly about in_atomic - if ($line =~ /\bin_atomic\s*\(/) { - if ($realfile =~ m@^drivers/@) { - ERROR("IN_ATOMIC", - "do not use in_atomic in drivers\n" . $herecurr); - } elsif ($realfile !~ m@^kernel/@) { - WARN("IN_ATOMIC", - "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); - } - } - -# check for mutex_trylock_recursive usage - if ($line =~ /mutex_trylock_recursive/) { - ERROR("LOCKING", - "recursive locking is bad, do not use this ever.\n" . $herecurr); - } - -# check for lockdep_set_novalidate_class - if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || - $line =~ /__lockdep_no_validate__\s*\)/ ) { - if ($realfile !~ m@^kernel/lockdep@ && - $realfile !~ m@^include/linux/lockdep@ && - $realfile !~ m@^drivers/base/core@) { - ERROR("LOCKDEP", - "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); - } - } - - if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ || - $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) { - WARN("EXPORTED_WORLD_WRITABLE", - "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); - } - -# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> -# and whether or not function naming is typical and if -# DEVICE_ATTR permissions uses are unusual too - if ($perl_version_ok && - defined $stat && - $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { - my $var = $1; - my $perms = $2; - my $show = $3; - my $store = $4; - my $octal_perms = perms_to_octal($perms); - if ($show =~ /^${var}_show$/ && - $store =~ /^${var}_store$/ && - $octal_perms eq "0644") { - if (WARN("DEVICE_ATTR_RW", - "Use DEVICE_ATTR_RW\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/; - } - } elsif ($show =~ /^${var}_show$/ && - $store =~ /^NULL$/ && - $octal_perms eq "0444") { - if (WARN("DEVICE_ATTR_RO", - "Use DEVICE_ATTR_RO\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/; - } - } elsif ($show =~ /^NULL$/ && - $store =~ /^${var}_store$/ && - $octal_perms eq "0200") { - if (WARN("DEVICE_ATTR_WO", - "Use DEVICE_ATTR_WO\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/; - } - } elsif ($octal_perms eq "0644" || - $octal_perms eq "0444" || - $octal_perms eq "0200") { - my $newshow = "$show"; - $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); - my $newstore = $store; - $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); - my $rename = ""; - if ($show ne $newshow) { - $rename .= " '$show' to '$newshow'"; - } - if ($store ne $newstore) { - $rename .= " '$store' to '$newstore'"; - } - WARN("DEVICE_ATTR_FUNCTIONS", - "Consider renaming function(s)$rename\n" . $herecurr); - } else { - WARN("DEVICE_ATTR_PERMS", - "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); - } - } - -# Mode permission misuses where it seems decimal should be octal -# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop -# o Ignore module_param*(...) uses with a decimal 0 permission as that has a -# specific definition of not visible in sysfs. -# o Ignore proc_create*(...) uses with a decimal 0 permission as that means -# use the default permissions - if ($perl_version_ok && - defined $stat && - $line =~ /$mode_perms_search/) { - foreach my $entry (@mode_permission_funcs) { - my $func = $entry->[0]; - my $arg_pos = $entry->[1]; - - my $lc = $stat =~ tr@\n@@; - $lc = $lc + $linenr; - my $stat_real = get_stat_real($linenr, $lc); - - my $skip_args = ""; - if ($arg_pos > 1) { - $arg_pos--; - $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}"; - } - my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]"; - if ($stat =~ /$test/) { - my $val = $1; - $val = $6 if ($skip_args ne ""); - if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") && - (($val =~ /^$Int$/ && $val !~ /^$Octal$/) || - ($val =~ /^$Octal$/ && length($val) ne 4))) { - ERROR("NON_OCTAL_PERMISSIONS", - "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real); - } - if ($val =~ /^$Octal$/ && (oct($val) & 02)) { - ERROR("EXPORTED_WORLD_WRITABLE", - "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real); - } - } - } - } - -# check for uses of S_<PERMS> that could be octal for readability - while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) { - my $oval = $1; - my $octal = perms_to_octal($oval); - if (WARN("SYMBOLIC_PERMS", - "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; - } - } - -# validate content of MODULE_LICENSE against list from include/linux/module.h - if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) { - my $extracted_string = get_quoted_string($line, $rawline); - my $valid_licenses = qr{ - GPL| - GPL\ v2| - GPL\ and\ additional\ rights| - Dual\ BSD/GPL| - Dual\ MIT/GPL| - Dual\ MPL/GPL| - Proprietary - }x; - if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) { - WARN("MODULE_LICENSE", - "unknown module license " . $extracted_string . "\n" . $herecurr); - } - } - -# check for sysctl duplicate constants - if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { - WARN("DUPLICATED_SYSCTL_CONST", - "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); - } - } - - # If we have no input at all, then there is nothing to report on - # so just keep quiet. - if ($#rawlines == -1) { - exit(0); - } - - # In mailback mode only produce a report in the negative, for - # things that appear to be patches. - if ($mailback && ($clean == 1 || !$is_patch)) { - exit(0); - } - - # This is not a patch, and we are are in 'no-patch' mode so - # just keep quiet. - if (!$chk_patch && !$is_patch) { - exit(0); - } - - if (!$is_patch && $filename !~ /cover-letter\.patch$/) { - ERROR("NOT_UNIFIED_DIFF", - "Does not appear to be a unified-diff format patch\n"); - } - if ($is_patch && $has_commit_log && $chk_signoff) { - if ($signoff == 0) { - ERROR("MISSING_SIGN_OFF", - "Missing Signed-off-by: line(s)\n"); - } elsif ($authorsignoff != 1) { - # authorsignoff values: - # 0 -> missing sign off - # 1 -> sign off identical - # 2 -> names and addresses match, comments mismatch - # 3 -> addresses match, names different - # 4 -> names match, addresses different - # 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match - - my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; - - if ($authorsignoff == 0) { - ERROR("NO_AUTHOR_SIGN_OFF", - "Missing Signed-off-by: line by nominal patch author '$author'\n"); - } elsif ($authorsignoff == 2) { - CHK("FROM_SIGN_OFF_MISMATCH", - "From:/Signed-off-by: email comments mismatch: $sob_msg\n"); - } elsif ($authorsignoff == 3) { - WARN("FROM_SIGN_OFF_MISMATCH", - "From:/Signed-off-by: email name mismatch: $sob_msg\n"); - } elsif ($authorsignoff == 4) { - WARN("FROM_SIGN_OFF_MISMATCH", - "From:/Signed-off-by: email address mismatch: $sob_msg\n"); - } elsif ($authorsignoff == 5) { - WARN("FROM_SIGN_OFF_MISMATCH", - "From:/Signed-off-by: email subaddress mismatch: $sob_msg\n"); - } - } - } - - print report_dump(); - if ($summary && !($clean == 1 && $quiet == 1)) { - print "$filename " if ($summary_file); - print "total: $cnt_error errors, $cnt_warn warnings, " . - (($check)? "$cnt_chk checks, " : "") . - "$cnt_lines lines checked\n"; - } - - if ($quiet == 0) { - # If there were any defects found and not already fixing them - if (!$clean and !$fix) { - print << "EOM" - -NOTE: For some of the reported defects, checkpatch may be able to - mechanically convert to the typical style using --fix or --fix-inplace. -EOM - } - # If there were whitespace errors which cleanpatch can fix - # then suggest that. - if ($rpt_cleaners) { - $rpt_cleaners = 0; - print << "EOM" - -NOTE: Whitespace errors detected. - You may wish to use scripts/cleanpatch or scripts/cleanfile -EOM - } - } - - if ($clean == 0 && $fix && - ("@rawlines" ne "@fixed" || - $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) { - my $newfile = $filename; - $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace); - my $linecount = 0; - my $f; - - @fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted); - - open($f, '>', $newfile) - or die "$P: Can't open $newfile for write\n"; - foreach my $fixed_line (@fixed) { - $linecount++; - if ($file) { - if ($linecount > 3) { - $fixed_line =~ s/^\+//; - print $f $fixed_line . "\n"; - } - } else { - print $f $fixed_line . "\n"; - } - } - close($f); - - if (!$quiet) { - print << "EOM"; - -Wrote EXPERIMENTAL --fix correction(s) to '$newfile' - -Do _NOT_ trust the results written to this file. -Do _NOT_ submit these changes without inspecting them for correctness. - -This EXPERIMENTAL file is simply a convenience to help rewrite patches. -No warranties, expressed or implied... -EOM - } - } - - if ($quiet == 0) { - print "\n"; - if ($clean == 1) { - print "$vname has no obvious style problems and is ready for submission.\n"; - } else { - print "$vname has style problems, please review.\n"; - } - } - return $clean; -} diff --git a/scripts/const_structs.checkpatch b/scripts/const_structs.checkpatch deleted file mode 100644 index 1aae4f4..0000000 --- a/scripts/const_structs.checkpatch +++ /dev/null @@ -1,68 +0,0 @@ -acpi_dock_ops -address_space_operations -backlight_ops -block_device_operations -clk_ops -comedi_lrange -component_ops -dentry_operations -dev_pm_ops -dma_map_ops -driver_info -drm_connector_funcs -drm_encoder_funcs -drm_encoder_helper_funcs -ethtool_ops -extent_io_ops -file_lock_operations -file_operations -hv_ops -ide_dma_ops -ide_port_ops -inode_operations -intel_dvo_dev_ops -irq_domain_ops -item_operations -iwl_cfg -iwl_ops -kgdb_arch -kgdb_io -kset_uevent_ops -lock_manager_operations -machine_desc -microcode_ops -mlxsw_reg_info -mtrr_ops -neigh_ops -net_device_ops -nlmsvc_binding -nvkm_device_chip -of_device_id -pci_raw_ops -phy_ops -pinctrl_ops -pinmux_ops -pipe_buf_operations -platform_hibernation_ops -platform_suspend_ops -proto_ops -regmap_access_table -regulator_ops -rpc_pipe_ops -rtc_class_ops -sd_desc -seq_operations -sirfsoc_padmux -snd_ac97_build_ops -snd_soc_component_driver -soc_pcmcia_socket_ops -stacktrace_ops -sysfs_ops -tty_operations -uart_ops -usb_mon_operations -v4l2_ctrl_ops -v4l2_ioctl_ops -vm_operations_struct -wacom_features -wd_ops diff --git a/scripts/spelling.txt b/scripts/spelling.txt deleted file mode 100644 index 953f4a2..0000000 --- a/scripts/spelling.txt +++ /dev/null @@ -1,1536 +0,0 @@ -# Originally from Debian's Lintian tool. Various false positives have been -# removed, and various additions have been made as they've been discovered -# in the kernel source. -# -# License: GPLv2 -# -# The format of each line is: -# mistake||correction -# -abandonning||abandoning -abigious||ambiguous -abitrary||arbitrary -abitrate||arbitrate -abnornally||abnormally -abnrormal||abnormal -abord||abort -aboslute||absolute -abov||above -abreviated||abbreviated -absense||absence -absolut||absolute -absoulte||absolute -acccess||access -acceess||access -acceleratoin||acceleration -accelleration||acceleration -accesing||accessing -accesnt||accent -accessable||accessible -accesss||access -accidentaly||accidentally -accidentually||accidentally -acclerated||accelerated -accoding||according -accomodate||accommodate -accomodates||accommodates -accordign||according -accoring||according -accout||account -accquire||acquire -accquired||acquired -accross||across -accumalate||accumulate -accumalator||accumulator -acessable||accessible -acess||access -acessing||accessing -achitecture||architecture -acient||ancient -acitions||actions -acitve||active -acknowldegement||acknowledgment -acknowledgement||acknowledgment -ackowledge||acknowledge -ackowledged||acknowledged -acording||according -activete||activate -actived||activated -actualy||actually -acumulating||accumulating -acumulative||accumulative -acumulator||accumulator -acutally||actually -adapater||adapter -addional||additional -additionaly||additionally -additonal||additional -addres||address -adddress||address -addreses||addresses -addresss||address -addrress||address -aditional||additional -aditionally||additionally -aditionaly||additionally -adminstrative||administrative -adress||address -adresses||addresses -adrresses||addresses -advertisment||advertisement -adviced||advised -afecting||affecting -againt||against -agaist||against -aggreataon||aggregation -aggreation||aggregation -albumns||albums -alegorical||allegorical -algined||aligned -algorith||algorithm -algorithmical||algorithmically -algoritm||algorithm -algoritms||algorithms -algorithmn||algorithm -algorrithm||algorithm -algorritm||algorithm -aligment||alignment -alignement||alignment -allign||align -alligned||aligned -alllocate||allocate -alloated||allocated -allocatote||allocate -allocatrd||allocated -allocte||allocate -allpication||application -alocate||allocate -alogirhtms||algorithms -alogrithm||algorithm -alot||a lot -alow||allow -alows||allows -alreay||already -alredy||already -altough||although -alue||value -ambigious||ambiguous -ambigous||ambiguous -amoung||among -amout||amount -amplifer||amplifier -amplifyer||amplifier -an union||a union -an user||a user -an userspace||a userspace -an one||a one -analysator||analyzer -ang||and -anniversery||anniversary -annoucement||announcement -anomolies||anomalies -anomoly||anomaly -anway||anyway -aplication||application -appearence||appearance -applicaion||application -appliction||application -applictions||applications -applys||applies -appplications||applications -appropiate||appropriate -appropriatly||appropriately -approriate||appropriate -approriately||appropriately -apropriate||appropriate -aquainted||acquainted -aquired||acquired -aquisition||acquisition -arbitary||arbitrary -architechture||architecture -arguement||argument -arguements||arguments -arithmatic||arithmetic -aritmetic||arithmetic -arne't||aren't -arraival||arrival -artifical||artificial -artillary||artillery -asign||assign -asser||assert -assertation||assertion -assertting||asserting -assiged||assigned -assigment||assignment -assigments||assignments -assistent||assistant -assocation||association -associcated||associated -assotiated||associated -asssert||assert -assum||assume -assumtpion||assumption -asuming||assuming -asycronous||asynchronous -asynchnous||asynchronous -asynchromous||asynchronous -asymetric||asymmetric -asymmeric||asymmetric -atomatically||automatically -atomicly||atomically -atempt||attempt -attachement||attachment -attatch||attach -attched||attached -attemp||attempt -attemps||attempts -attemping||attempting -attepmpt||attempt -attnetion||attention -attruibutes||attributes -authentification||authentication -authenicated||authenticated -automaticaly||automatically -automaticly||automatically -automatize||automate -automatized||automated -automatizes||automates -autonymous||autonomous -auxillary||auxiliary -auxilliary||auxiliary -avaiable||available -avaible||available -availabe||available -availabled||available -availablity||availability -availaible||available -availale||available -availavility||availability -availble||available -availiable||available -availible||available -avalable||available -avaliable||available -aysnc||async -backgroud||background -backword||backward -backwords||backwards -bahavior||behavior -bakup||backup -baloon||balloon -baloons||balloons -bandwith||bandwidth -banlance||balance -batery||battery -beacuse||because -becasue||because -becomming||becoming -becuase||because -beeing||being -befor||before -begining||beginning -beter||better -betweeen||between -bianries||binaries -bitmast||bitmask -boardcast||broadcast -borad||board -boundry||boundary -brievely||briefly -brigde||bridge -broadcase||broadcast -broadcat||broadcast -bufer||buffer -bufufer||buffer -cacluated||calculated -caculate||calculate -caculation||calculation -cadidate||candidate -cahces||caches -calender||calendar -calescing||coalescing -calle||called -callibration||calibration -callled||called -callser||caller -calucate||calculate -calulate||calculate -cancelation||cancellation -cancle||cancel -capabilites||capabilities -capabilties||capabilities -capabilty||capability -capabitilies||capabilities -capablity||capability -capatibilities||capabilities -capapbilities||capabilities -caputure||capture -carefuly||carefully -cariage||carriage -catagory||category -cehck||check -challange||challenge -challanges||challenges -chache||cache -chanell||channel -changable||changeable -chanined||chained -channle||channel -channnel||channel -charachter||character -charachters||characters -charactor||character -charater||character -charaters||characters -charcter||character -chcek||check -chck||check -checksumed||checksummed -checksuming||checksumming -childern||children -childs||children -chiled||child -chked||checked -chnage||change -chnages||changes -chnnel||channel -choosen||chosen -chouse||chose -circumvernt||circumvent -claread||cleared -clared||cleared -closeing||closing -clustred||clustered -cnfiguration||configuration -coexistance||coexistence -colescing||coalescing -collapsable||collapsible -colorfull||colorful -comand||command -comit||commit -commerical||commercial -comming||coming -comminucation||communication -commited||committed -commiting||committing -committ||commit -commoditiy||commodity -comsume||consume -comsumer||consumer -comsuming||consuming -compability||compatibility -compaibility||compatibility -comparsion||comparison -compatability||compatibility -compatable||compatible -compatibililty||compatibility -compatibiliy||compatibility -compatibilty||compatibility -compatiblity||compatibility -competion||completion -compilant||compliant -compleatly||completely -completition||completion -completly||completely -complient||compliant -componnents||components -compoment||component -comppatible||compatible -compres||compress -compresion||compression -comression||compression -comunication||communication -conbination||combination -conditionaly||conditionally -conditon||condition -condtion||condition -conected||connected -conector||connector -configration||configuration -configuartion||configuration -configuation||configuration -configued||configured -configuratoin||configuration -configuraton||configuration -configuretion||configuration -configutation||configuration -conider||consider -conjuction||conjunction -connecetd||connected -connectinos||connections -connetor||connector -connnection||connection -connnections||connections -consistancy||consistency -consistant||consistent -containes||contains -containts||contains -contaisn||contains -contant||contact -contence||contents -contiguos||contiguous -continious||continuous -continous||continuous -continously||continuously -continueing||continuing -contraints||constraints -contruct||construct -contol||control -contoller||controller -controled||controlled -controler||controller -controll||control -contruction||construction -contry||country -conuntry||country -convertion||conversion -convertor||converter -convienient||convenient -convinient||convenient -corected||corrected -correponding||corresponding -correponds||corresponds -correspoding||corresponding -cotrol||control -cound||could -couter||counter -coutner||counter -cryptocraphic||cryptographic -cunter||counter -curently||currently -cylic||cyclic -dafault||default -deafult||default -deamon||daemon -debouce||debounce -decendant||descendant -decendants||descendants -decompres||decompress -decsribed||described -decription||description -dectected||detected -defailt||default -deferal||deferral -deffered||deferred -defferred||deferred -definate||definite -definately||definitely -defintion||definition -defintions||definitions -defualt||default -defult||default -deintializing||deinitializing -deintialize||deinitialize -deintialized||deinitialized -deivce||device -delared||declared -delare||declare -delares||declares -delaring||declaring -delemiter||delimiter -delievered||delivered -demodualtor||demodulator -demension||dimension -dependancies||dependencies -dependancy||dependency -dependant||dependent -dependend||dependent -depreacted||deprecated -depreacte||deprecate -desactivate||deactivate -desciptor||descriptor -desciptors||descriptors -descripto||descriptor -descripton||description -descrition||description -descritptor||descriptor -desctiptor||descriptor -desriptor||descriptor -desriptors||descriptors -desination||destination -destionation||destination -destoried||destroyed -destory||destroy -destoryed||destroyed -destorys||destroys -destroied||destroyed -detabase||database -deteced||detected -detectt||detect -develope||develop -developement||development -developped||developed -developpement||development -developper||developer -developpment||development -deveolpment||development -devided||divided -deviece||device -diable||disable -dicline||decline -dictionnary||dictionary -didnt||didn't -diferent||different -differrence||difference -diffrent||different -differenciate||differentiate -diffrentiate||differentiate -difinition||definition -digial||digital -dimention||dimension -dimesions||dimensions -disgest||digest -dispalying||displaying -diplay||display -directon||direction -direcly||directly -direectly||directly -diregard||disregard -disassocation||disassociation -disapear||disappear -disapeared||disappeared -disappared||disappeared -disbale||disable -disbaled||disabled -disble||disable -disbled||disabled -disconnet||disconnect -discontinous||discontinuous -disharge||discharge -disnabled||disabled -dispertion||dispersion -dissapears||disappears -dissconect||disconnect -distiction||distinction -divisable||divisible -divsiors||divisors -docuentation||documentation -documantation||documentation -documentaion||documentation -documment||document -doesnt||doesn't -donwload||download -donwloading||downloading -dorp||drop -dosen||doesn -downlad||download -downlads||downloads -droped||dropped -droput||dropout -druing||during -dynmaic||dynamic -eanable||enable -eanble||enable -easilly||easily -ecspecially||especially -edditable||editable -editting||editing -efective||effective -effectivness||effectiveness -efficently||efficiently -ehther||ether -eigth||eight -elementry||elementary -eletronic||electronic -embeded||embedded -enabledi||enabled -enbale||enable -enble||enable -enchanced||enhanced -encorporating||incorporating -encrupted||encrypted -encrypiton||encryption -encryptio||encryption -endianess||endianness -enhaced||enhanced -enlightnment||enlightenment -enqueing||enqueuing -entires||entries -entites||entities -entrys||entries -enocded||encoded -enought||enough -enterily||entirely -enviroiment||environment -enviroment||environment -environement||environment -environent||environment -eqivalent||equivalent -equiped||equipped -equivelant||equivalent -equivilant||equivalent -eror||error -errorr||error -errror||error -estbalishment||establishment -etsablishment||establishment -etsbalishment||establishment -evalution||evaluation -excecutable||executable -exceded||exceeded -exceds||exceeds -exceeed||exceed -excellant||excellent -execeeded||exceeded -execeeds||exceeds -exeed||exceed -exeuction||execution -existance||existence -existant||existent -exixt||exist -exlcude||exclude -exlcusive||exclusive -exmaple||example -expecially||especially -experies||expires -explicite||explicit -explicitely||explicitly -explict||explicit -explictely||explicitly -explictly||explicitly -expresion||expression -exprimental||experimental -extened||extended -exteneded||extended -extensability||extensibility -extention||extension -extenstion||extension -extracter||extractor -faied||failed -faield||failed -faild||failed -failded||failed -failer||failure -faill||fail -failied||failed -faillure||failure -failue||failure -failuer||failure -failng||failing -faireness||fairness -falied||failed -faliure||failure -fallbck||fallback -familar||familiar -fatser||faster -feauture||feature -feautures||features -fetaure||feature -fetaures||features -fileystem||filesystem -fimrware||firmware -fimware||firmware -firmare||firmware -firmaware||firmware -firware||firmware -firwmare||firmware -finanize||finalize -findn||find -finilizes||finalizes -finsih||finish -flusing||flushing -folloing||following -followign||following -followings||following -follwing||following -fonud||found -forseeable||foreseeable -forse||force -fortan||fortran -forwardig||forwarding -frambuffer||framebuffer -framming||framing -framwork||framework -frequncy||frequency -frequancy||frequency -frome||from -fucntion||function -fuction||function -fuctions||functions -fullill||fulfill -funcation||function -funcion||function -functionallity||functionality -functionaly||functionally -functionnality||functionality -functonality||functionality -funtion||function -funtions||functions -furthur||further -futhermore||furthermore -futrue||future -gatable||gateable -gateing||gating -gauage||gauge -gaurenteed||guaranteed -generiously||generously -genereate||generate -genereted||generated -genric||generic -globel||global -grabing||grabbing -grahical||graphical -grahpical||graphical -granularty||granularity -grapic||graphic -grranted||granted -guage||gauge -guarenteed||guaranteed -guarentee||guarantee -halfs||halves -hander||handler -handfull||handful -hanlde||handle -hanled||handled -happend||happened -harware||hardware -havind||having -heirarchically||hierarchically -helpfull||helpful -hexdecimal||hexadecimal -hybernate||hibernate -hierachy||hierarchy -hierarchie||hierarchy -homogenous||homogeneous -howver||however -hsould||should -hypervior||hypervisor -hypter||hyper -identidier||identifier -iligal||illegal -illigal||illegal -illgal||illegal -iomaped||iomapped -imblance||imbalance -immeadiately||immediately -immedaite||immediate -immedate||immediate -immediatelly||immediately -immediatly||immediately -immidiate||immediate -immutible||immutable -impelentation||implementation -impementated||implemented -implemantation||implementation -implemenation||implementation -implementaiton||implementation -implementated||implemented -implemention||implementation -implementd||implemented -implemetation||implementation -implemntation||implementation -implentation||implementation -implmentation||implementation -implmenting||implementing -incative||inactive -incomming||incoming -incompatabilities||incompatibilities -incompatable||incompatible -incompatble||incompatible -inconsistant||inconsistent -increas||increase -incremeted||incremented -incrment||increment -inculde||include -indendation||indentation -indended||intended -independant||independent -independantly||independently -independed||independent -indiate||indicate -indicat||indicate -inexpect||inexpected -inferface||interface -infomation||information -informatiom||information -informations||information -informtion||information -infromation||information -ingore||ignore -inital||initial -initalized||initialized -initalised||initialized -initalise||initialize -initalize||initialize -initation||initiation -initators||initiators -initialiazation||initialization -initializationg||initialization -initializiation||initialization -initialze||initialize -initialzed||initialized -initialzing||initializing -initilization||initialization -initilize||initialize -initliaze||initialize -initilized||initialized -inofficial||unofficial -inrerface||interface -insititute||institute -instace||instance -instal||install -instanciate||instantiate -instanciated||instantiated -insufficent||insufficient -inteface||interface -integreated||integrated -integrety||integrity -integrey||integrity -intendet||intended -intented||intended -interanl||internal -interchangable||interchangeable -interferring||interfering -interger||integer -intermittant||intermittent -internel||internal -interoprability||interoperability -interuupt||interrupt -interupt||interrupt -interupts||interrupts -interrface||interface -interrrupt||interrupt -interrup||interrupt -interrups||interrupts -interruptted||interrupted -interupted||interrupted -intial||initial -intialisation||initialisation -intialised||initialised -intialise||initialise -intialization||initialization -intialized||initialized -intialize||initialize -intregral||integral -intrerrupt||interrupt -intrrupt||interrupt -intterrupt||interrupt -intuative||intuitive -inavlid||invalid -invaid||invalid -invaild||invalid -invailid||invalid -invald||invalid -invalde||invalid -invalide||invalid -invalidiate||invalidate -invalud||invalid -invididual||individual -invokation||invocation -invokations||invocations -ireelevant||irrelevant -irrelevent||irrelevant -isnt||isn't -isssue||issue -issus||issues -iteraions||iterations -iternations||iterations -itertation||iteration -itslef||itself -jave||java -jeffies||jiffies -jumpimng||jumping -juse||just -jus||just -kown||known -langage||language -langauage||language -langauge||language -langugage||language -lauch||launch -layed||laid -legnth||length -leightweight||lightweight -lengh||length -lenght||length -lenth||length -lesstiff||lesstif -libaries||libraries -libary||library -librairies||libraries -libraris||libraries -licenceing||licencing -limted||limited -logaritmic||logarithmic -loggging||logging -loggin||login -logile||logfile -loobpack||loopback -loosing||losing -losted||lost -maangement||management -machinary||machinery -maibox||mailbox -maintainance||maintenance -maintainence||maintenance -maintan||maintain -makeing||making -mailformed||malformed -malplaced||misplaced -malplace||misplace -managable||manageable -managment||management -mangement||management -manger||manager -manoeuvering||maneuvering -manufaucturing||manufacturing -mappping||mapping -matchs||matches -mathimatical||mathematical -mathimatic||mathematic -mathimatics||mathematics -maximium||maximum -maxium||maximum -mechamism||mechanism -meetign||meeting -memeory||memory -memmber||member -memoery||memory -ment||meant -mergable||mergeable -mesage||message -messags||messages -messgaes||messages -messsage||message -messsages||messages -metdata||metadata -micropone||microphone -microprocesspr||microprocessor -migrateable||migratable -milliseonds||milliseconds -minium||minimum -minimam||minimum -miniumum||minimum -minumum||minimum -misalinged||misaligned -miscelleneous||miscellaneous -misformed||malformed -mispelled||misspelled -mispelt||misspelt -mising||missing -mismactch||mismatch -missign||missing -missmanaged||mismanaged -missmatch||mismatch -misssing||missing -miximum||maximum -mmnemonic||mnemonic -mnay||many -modfiy||modify -modifer||modifier -modulues||modules -momery||memory -memomry||memory -monitring||monitoring -monochorome||monochrome -monochromo||monochrome -monocrome||monochrome -mopdule||module -mroe||more -multipler||multiplier -mulitplied||multiplied -multidimensionnal||multidimensional -multipe||multiple -multple||multiple -mumber||number -muticast||multicast -mutilcast||multicast -mutiple||multiple -mutli||multi -nams||names -navagating||navigating -nead||need -neccecary||necessary -neccesary||necessary -neccessary||necessary -necesary||necessary -neded||needed -negaive||negative -negoitation||negotiation -negotation||negotiation -nerver||never -nescessary||necessary -nessessary||necessary -noticable||noticeable -notication||notification -notications||notifications -notifcations||notifications -notifed||notified -notity||notify -numebr||number -numner||number -obtaion||obtain -obusing||abusing -occassionally||occasionally -occationally||occasionally -occurance||occurrence -occurances||occurrences -occurd||occurred -occured||occurred -occurence||occurrence -occure||occurred -occuring||occurring -offser||offset -offet||offset -offlaod||offload -offloded||offloaded -offseting||offsetting -omited||omitted -omiting||omitting -omitt||omit -ommiting||omitting -ommitted||omitted -onself||oneself -ony||only -operatione||operation -opertaions||operations -optionnal||optional -optmizations||optimizations -orientatied||orientated -orientied||oriented -orignal||original -originial||original -otherise||otherwise -ouput||output -oustanding||outstanding -overaall||overall -overhread||overhead -overlaping||overlapping -overide||override -overrided||overridden -overriden||overridden -overun||overrun -overwritting||overwriting -overwriten||overwritten -pacakge||package -pachage||package -packacge||package -packege||package -packge||package -packtes||packets -pakage||package -paket||packet -pallette||palette -paln||plan -paramameters||parameters -paramaters||parameters -paramater||parameter -parametes||parameters -parametised||parametrised -paramter||parameter -paramters||parameters -parmaters||parameters -particuarly||particularly -particularily||particularly -partion||partition -partions||partitions -partiton||partition -pased||passed -passin||passing -pathes||paths -pattrns||patterns -pecularities||peculiarities -peformance||performance -peforming||performing -peice||piece -pendantic||pedantic -peprocessor||preprocessor -perfoming||performing -perfomring||performing -periperal||peripheral -peripherial||peripheral -permissons||permissions -peroid||period -persistance||persistence -persistant||persistent -phoneticly||phonetically -plalform||platform -platfoem||platform -platfrom||platform -plattform||platform -pleaes||please -ploting||plotting -plugable||pluggable -poinnter||pointer -pointeur||pointer -poiter||pointer -posible||possible -positon||position -possibilites||possibilities -potocol||protocol -powerfull||powerful -pramater||parameter -preamle||preamble -preample||preamble -preapre||prepare -preceeded||preceded -preceeding||preceding -preceed||precede -precendence||precedence -precission||precision -preemptable||preemptible -prefered||preferred -prefferably||preferably -prefitler||prefilter -premption||preemption -prepaired||prepared -preperation||preparation -preprare||prepare -pressre||pressure -primative||primitive -princliple||principle -priorty||priority -privilaged||privileged -privilage||privilege -priviledge||privilege -priviledges||privileges -probaly||probably -procceed||proceed -proccesors||processors -procesed||processed -proces||process -procesing||processing -processessing||processing -processess||processes -processpr||processor -processsed||processed -processsing||processing -procteted||protected -prodecure||procedure -progamming||programming -progams||programs -progess||progress -programers||programmers -programm||program -programms||programs -progresss||progress -prohibitted||prohibited -prohibitting||prohibiting -promiscous||promiscuous -promps||prompts -pronnounced||pronounced -prononciation||pronunciation -pronouce||pronounce -pronunce||pronounce -propery||property -propigate||propagate -propigation||propagation -propogation||propagation -propogate||propagate -prosess||process -protable||portable -protcol||protocol -protecion||protection -protedcted||protected -protocoll||protocol -promixity||proximity -psudo||pseudo -psuedo||pseudo -psychadelic||psychedelic -pwoer||power -queing||queuing -quering||querying -queus||queues -randomally||randomly -raoming||roaming -reasearcher||researcher -reasearchers||researchers -reasearch||research -receieve||receive -recepient||recipient -recevied||received -receving||receiving -recieved||received -recieve||receive -reciever||receiver -recieves||receives -recogniced||recognised -recognizeable||recognizable -recommanded||recommended -recyle||recycle -redircet||redirect -redirectrion||redirection -redundacy||redundancy -reename||rename -refcounf||refcount -refence||reference -refered||referred -referenace||reference -refering||referring -refernces||references -refernnce||reference -refrence||reference -registed||registered -registerd||registered -registeration||registration -registeresd||registered -registerred||registered -registes||registers -registraration||registration -regsiter||register -regster||register -regualar||regular -reguator||regulator -regulamentations||regulations -reigstration||registration -releated||related -relevent||relevant -reloade||reload -remoote||remote -remore||remote -removeable||removable -repectively||respectively -replacable||replaceable -replacments||replacements -replys||replies -reponse||response -representaion||representation -reqeust||request -reqister||register -requestied||requested -requiere||require -requirment||requirement -requred||required -requried||required -requst||request -requsted||requested -reregisteration||reregistration -reseting||resetting -reseved||reserved -reseverd||reserved -resizeable||resizable -resouce||resource -resouces||resources -resoures||resources -responce||response -resrouce||resource -ressizes||resizes -ressource||resource -ressources||resources -restesting||retesting -resumbmitting||resubmitting -retransmited||retransmitted -retreived||retrieved -retreive||retrieve -retreiving||retrieving -retrive||retrieve -retrived||retrieved -retrun||return -retun||return -retuned||returned -reudce||reduce -reuest||request -reuqest||request -reutnred||returned -revsion||revision -rmeoved||removed -rmeove||remove -rmeoves||removes -rountine||routine -routins||routines -rquest||request -runing||running -runned||ran -runnning||running -runtine||runtime -sacrifying||sacrificing -safly||safely -safty||safety -savable||saveable -scaleing||scaling -scaned||scanned -scaning||scanning -scarch||search -schdule||schedule -seach||search -searchs||searches -secquence||sequence -secund||second -segement||segment -semaphone||semaphore -senario||scenario -senarios||scenarios -sentivite||sensitive -separatly||separately -sepcify||specify -seperated||separated -seperately||separately -seperate||separate -seperatly||separately -seperator||separator -sepperate||separate -seqeunce||sequence -seqeuncer||sequencer -seqeuencer||sequencer -sequece||sequence -sequencial||sequential -serivce||service -serveral||several -servive||service -setts||sets -settting||setting -shapshot||snapshot -shotdown||shutdown -shoud||should -shouldnt||shouldn't -shoule||should -shrinked||shrunk -siginificantly||significantly -signabl||signal -significanly||significantly -similary||similarly -similiar||similar -simlar||similar -simliar||similar -simpified||simplified -singaled||signaled -singal||signal -singed||signed -sleeped||slept -sliped||slipped -softwares||software -speach||speech -specfic||specific -specfield||specified -speciefied||specified -specifc||specific -specifed||specified -specificatin||specification -specificaton||specification -specifing||specifying -specifiying||specifying -speficied||specified -speicify||specify -speling||spelling -spinlcok||spinlock -spinock||spinlock -splitted||split -spreaded||spread -spurrious||spurious -sructure||structure -stablilization||stabilization -staically||statically -staion||station -standardss||standards -standartization||standardization -standart||standard -standy||standby -stardard||standard -staticly||statically -statuss||status -stoped||stopped -stoping||stopping -stoppped||stopped -straming||streaming -struc||struct -structres||structures -stuct||struct -strucuture||structure -stucture||structure -sturcture||structure -subdirectoires||subdirectories -suble||subtle -substract||subtract -submited||submitted -submition||submission -suceed||succeed -succesfully||successfully -succesful||successful -successed||succeeded -successfull||successful -successfuly||successfully -sucessfully||successfully -sucessful||successful -sucess||success -superflous||superfluous -superseeded||superseded -suplied||supplied -suported||supported -suport||support -supportet||supported -suppored||supported -supportin||supporting -suppoted||supported -suppported||supported -suppport||support -supress||suppress -surpressed||suppressed -surpresses||suppresses -susbsystem||subsystem -suspeneded||suspended -suspsend||suspend -suspicously||suspiciously -swaping||swapping -switchs||switches -swith||switch -swithable||switchable -swithc||switch -swithced||switched -swithcing||switching -swithed||switched -swithing||switching -swtich||switch -syfs||sysfs -symetric||symmetric -synax||syntax -synchonized||synchronized -synchronuously||synchronously -syncronize||synchronize -syncronized||synchronized -syncronizing||synchronizing -syncronus||synchronous -syste||system -sytem||system -sythesis||synthesis -taht||that -tansmit||transmit -targetted||targeted -targetting||targeting -taskelt||tasklet -teh||the -temorary||temporary -temproarily||temporarily -temperture||temperature -thead||thread -therfore||therefore -thier||their -threds||threads -threee||three -threshhold||threshold -thresold||threshold -throught||through -trackling||tracking -troughput||throughput -thses||these -tiggers||triggers -tiggered||triggered -tipically||typically -timeing||timing -timout||timeout -tmis||this -toogle||toggle -torerable||tolerable -traking||tracking -tramsmitted||transmitted -tramsmit||transmit -tranasction||transaction -tranfer||transfer -transcevier||transceiver -transciever||transceiver -transferd||transferred -transfered||transferred -transfering||transferring -transision||transition -transmittd||transmitted -transormed||transformed -trasfer||transfer -trasmission||transmission -treshold||threshold -triggerd||triggered -trigerred||triggered -trigerring||triggering -trun||turn -tunning||tuning -ture||true -tyep||type -udpate||update -uesd||used -uknown||unknown -usccess||success -uncommited||uncommitted -uncompatible||incompatible -unconditionaly||unconditionally -undeflow||underflow -underun||underrun -unecessary||unnecessary -unexecpted||unexpected -unexepected||unexpected -unexpcted||unexpected -unexpectd||unexpected -unexpeted||unexpected -unexpexted||unexpected -unfortunatelly||unfortunately -unifiy||unify -uniterrupted||uninterrupted -unintialized||uninitialized -unitialized||uninitialized -unkmown||unknown -unknonw||unknown -unknow||unknown -unkown||unknown -unamed||unnamed -uneeded||unneeded -unneded||unneeded -unneccecary||unnecessary -unneccesary||unnecessary -unneccessary||unnecessary -unnecesary||unnecessary -unneedingly||unnecessarily -unnsupported||unsupported -unmached||unmatched -unregester||unregister -unresgister||unregister -unrgesiter||unregister -unsinged||unsigned -unstabel||unstable -unsolicitied||unsolicited -unsuccessfull||unsuccessful -unsuported||unsupported -untill||until -ununsed||unused -unuseful||useless -unvalid||invalid -upate||update -upsupported||unsupported -usefule||useful -usefull||useful -usege||usage -usera||users -usualy||usually -usupported||unsupported -utilites||utilities -utillities||utilities -utilties||utilities -utiltity||utility -utitity||utility -utitlty||utility -vaid||valid -vaild||valid -valide||valid -variantions||variations -varible||variable -varient||variant -vaule||value -verbse||verbose -veify||verify -verisons||versions -verison||version -verson||version -vicefersa||vice-versa -virtal||virtual -virtaul||virtual -virtiual||virtual -visiters||visitors -vitual||virtual -vunerable||vulnerable -wakeus||wakeups -wathdog||watchdog -wating||waiting -wiat||wait -wether||whether -whataver||whatever -whcih||which -whenver||whenever -wheter||whether -whe||when -wierd||weird -wiil||will -wirte||write -withing||within -wnat||want -workarould||workaround -writeing||writing -writting||writing -wtih||with -zombe||zombie -zomebie||zombie